diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java index 86a6cfd..fd29b7f 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java @@ -69,14 +69,16 @@ public class PlaceholderAPI { * @return true if the hook was successfully registered, false if there is already a hook * registered for the specified identifier */ - public static boolean registerPlaceholderHook(String identifier, - PlaceholderHook placeholderHook) { + public static boolean registerPlaceholderHook(String identifier, PlaceholderHook placeholderHook) { Validate.notNull(identifier, "Identifier can not be null"); Validate.notNull(placeholderHook, "Placeholderhook can not be null"); + if (isRegistered(identifier)) { return false; } + placeholders.put(identifier.toLowerCase(), placeholderHook); + return true; } @@ -114,6 +116,7 @@ public class PlaceholderAPI { Set set = getPlaceholders().values().stream() .filter(PlaceholderExpansion.class::isInstance).map(PlaceholderExpansion.class::cast) .collect(Collectors.toCollection(HashSet::new)); + return ImmutableSet.copyOf(set); } @@ -174,6 +177,7 @@ public class PlaceholderAPI { if (text == null) { return null; } + return text.stream().map(line -> setPlaceholders(p, line, pattern)) .collect(Collectors.toList()); } @@ -212,24 +216,29 @@ public class PlaceholderAPI { * underscore separating the identifier from the params * @return text with all placeholders set to the corresponding values */ - public static String setPlaceholders(OfflinePlayer player, String text, - Pattern placeholderPattern) { + public static String setPlaceholders(OfflinePlayer player, String text, Pattern placeholderPattern) { if (text == null) { return null; } + if (placeholders.isEmpty()) { return color(text); } + Matcher m = placeholderPattern.matcher(text); Map hooks = getPlaceholders(); + while (m.find()) { String format = m.group(1); int index = format.indexOf("_"); + if (index <= 0 || index >= format.length()) { continue; } + String identifier = format.substring(0, index).toLowerCase(); String params = format.substring(index + 1); + if (hooks.containsKey(identifier)) { String value = hooks.get(identifier).onRequest(player, params); if (value != null) { @@ -237,6 +246,7 @@ public class PlaceholderAPI { } } } + return color(text); } @@ -253,6 +263,7 @@ public class PlaceholderAPI { if (text == null) { return null; } + return text.stream().map(line -> setRelationalPlaceholders(one, two, line)) .collect(Collectors.toList()); } @@ -270,30 +281,39 @@ public class PlaceholderAPI { if (text == null) { return null; } + if (placeholders.isEmpty()) { return color(text); } + Matcher m = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text); Map hooks = getPlaceholders(); + while (m.find()) { String format = m.group(2); int index = format.indexOf("_"); + if (index <= 0 || index >= format.length()) { continue; } + String identifier = format.substring(0, index).toLowerCase(); String params = format.substring(index + 1); + if (hooks.containsKey(identifier)) { if (!(hooks.get(identifier) instanceof Relational)) { continue; } + Relational rel = (Relational) hooks.get(identifier); String value = rel.onPlaceholderRequest(one, two, params); + if (value != null) { text = text.replaceAll(Pattern.quote(m.group()), Matcher.quoteReplacement(value)); } } } + return color(text); } @@ -312,9 +332,11 @@ public class PlaceholderAPI { if (placeholders.isEmpty()) { return; } + getPlaceholders().forEach((key, value) -> { if (value instanceof PlaceholderExpansion) { PlaceholderExpansion ex = (PlaceholderExpansion) value; + if (!ex.persist()) { unregisterExpansion(ex); } @@ -328,6 +350,7 @@ public class PlaceholderAPI { if (ev.isCancelled()) { return false; } + return registerPlaceholderHook(ex.getIdentifier(), ex); } @@ -336,6 +359,7 @@ public class PlaceholderAPI { Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(ex)); return true; } + return false; } @@ -372,18 +396,18 @@ public class PlaceholderAPI { } public static String setPlaceholders(Player p, String text) { - return setPlaceholders((OfflinePlayer) p, text, PLACEHOLDER_PATTERN); + return setPlaceholders(p, text, PLACEHOLDER_PATTERN); } public static List setPlaceholders(Player p, List text) { - return setPlaceholders((OfflinePlayer) p, text, PLACEHOLDER_PATTERN); + return setPlaceholders(p, text, PLACEHOLDER_PATTERN); } public static String setBracketPlaceholders(Player p, String text) { - return setPlaceholders((OfflinePlayer) p, text, BRACKET_PLACEHOLDER_PATTERN); + return setPlaceholders(p, text, BRACKET_PLACEHOLDER_PATTERN); } public static List setBracketPlaceholders(Player p, List text) { - return setPlaceholders((OfflinePlayer) p, text, BRACKET_PLACEHOLDER_PATTERN); + return setPlaceholders(p, text, BRACKET_PLACEHOLDER_PATTERN); } } diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java index e76d9a9..9830b21 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java @@ -61,17 +61,20 @@ public class PlaceholderAPIPlugin extends JavaPlugin { private static Version getVersion() { String v = "unknown"; boolean spigot = false; + try { v = Bukkit.getServer().getClass().getPackage().getName() .split("\\.")[3]; } catch (ArrayIndexOutOfBoundsException ex) { } + try { Class.forName("org.spigotmc.SpigotConfig"); Class.forName("net.md_5.bungee.api.chat.BaseComponent"); spigot = true; } catch (ExceptionInInitializerError | ClassNotFoundException exception) { } + return new Version(v, spigot); } @@ -132,28 +135,35 @@ public class PlaceholderAPIPlugin extends JavaPlugin { public void onEnable() { config.loadDefConfig(); setupOptions(); + getCommand("placeholderapi").setExecutor(new PlaceholderAPICommands(this)); new PlaceholderListener(this); + try { Class.forName("org.bukkit.event.server.ServerLoadEvent"); new ServerLoadEventListener(this); } catch (ExceptionInInitializerError | ClassNotFoundException exception) { Bukkit.getScheduler().runTaskLater(this, () -> { getLogger().info("Placeholder expansion registration initializing..."); + //fetch any hooks that may have registered externally onEnable first otherwise they will be lost final Map alreadyRegistered = PlaceholderAPI.getPlaceholders(); getExpansionManager().registerAllExpansions(); + if (alreadyRegistered != null && !alreadyRegistered.isEmpty()) { alreadyRegistered.forEach(PlaceholderAPI::registerPlaceholderHook); } }, 1); } + if (config.checkUpdates()) { new UpdateChecker(this).fetch(); } + if (config.isCloudEnabled()) { enableCloud(); } + setupMetrics(); getServer().getScheduler().runTaskLater(this, this::checkHook, 40); } @@ -174,11 +184,13 @@ public class PlaceholderAPIPlugin extends JavaPlugin { reloadConfig(); setupOptions(); expansionManager.registerAllExpansions(); + if (!config.isCloudEnabled()) { disableCloud(); } else if (!cloudEnabled) { enableCloud(); } + s.sendMessage(ChatColor.translateAlternateColorCodes('&', PlaceholderAPI.getRegisteredIdentifiers().size() + " &aplaceholder hooks successfully registered!")); @@ -186,31 +198,40 @@ public class PlaceholderAPIPlugin extends JavaPlugin { private void checkHook() { Map loaded = PlaceholderAPI.getPlaceholders(); + loaded.values().forEach(h -> { - if (h instanceof EZPlaceholderHook) { - String author; - try { - author = Bukkit.getPluginManager().getPlugin(((EZPlaceholderHook) h).getPluginName()).getDescription().getAuthors().toString(); - } catch (Exception ex) { - author = "the author of the hook's plugin"; + if (h instanceof EZPlaceholderHook) { + String author; + + try { + author = Bukkit.getPluginManager().getPlugin(((EZPlaceholderHook) h).getPluginName()).getDescription().getAuthors().toString(); + } catch (Exception ex) { + author = "the author of the hook's plugin"; + } + + getLogger().severe(((EZPlaceholderHook) h).getPluginName() + + " is currently using a deprecated method to hook into PlaceholderAPI. Placeholders for that plugin no longer work. " + + "Please consult {author} and urge them to update it ASAP.".replace("{author}", author)); + + // disable the hook on startup + PlaceholderAPI.unregisterPlaceholderHook(((EZPlaceholderHook) h).getPlaceholderName()); } - getLogger().severe(((EZPlaceholderHook) h).getPluginName() + " is currently using a deprecated method to hook into PlaceholderAPI. Placeholders for that plugin no longer work. " + - "Please consult {author} and urge them to update it ASAP.".replace("{author}", author)); - // disable the hook on startup - PlaceholderAPI.unregisterPlaceholderHook(((EZPlaceholderHook) h).getPlaceholderName()); - } }); } private void setupOptions() { booleanTrue = config.booleanTrue(); + if (booleanTrue == null) { booleanTrue = "true"; } + booleanFalse = config.booleanFalse(); + if (booleanFalse == null) { booleanFalse = "false"; } + try { dateFormat = new SimpleDateFormat(config.dateFormat()); } catch (Exception e) { diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderHook.java b/src/main/java/me/clip/placeholderapi/PlaceholderHook.java index 7d92da0..c70c386 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderHook.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderHook.java @@ -37,6 +37,7 @@ public abstract class PlaceholderHook { if (p != null && p.isOnline()) { return onPlaceholderRequest((Player) p, params); } + return onPlaceholderRequest(null, params); } diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderListener.java b/src/main/java/me/clip/placeholderapi/PlaceholderListener.java index 539e859..d2685cb 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderListener.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderListener.java @@ -41,7 +41,7 @@ import java.util.Set; public class PlaceholderListener implements Listener { - private PlaceholderAPIPlugin plugin; + private final PlaceholderAPIPlugin plugin; public PlaceholderListener(PlaceholderAPIPlugin instance) { plugin = instance; @@ -50,7 +50,6 @@ public class PlaceholderListener implements Listener { @EventHandler public void onExpansionUnregister(ExpansionUnregisterEvent event) { - if (event.getExpansion() instanceof Listener) { HandlerList.unregisterAll((Listener) event.getExpansion()); } @@ -77,7 +76,6 @@ public class PlaceholderListener implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onPluginUnload(PluginDisableEvent e) { - String n = e.getPlugin().getName(); if (n == null) { @@ -91,11 +89,9 @@ public class PlaceholderListener implements Listener { Map hooks = PlaceholderAPI.getPlaceholders(); for (Entry hook : hooks.entrySet()) { - PlaceholderHook i = hook.getValue(); if (i instanceof PlaceholderExpansion) { - PlaceholderExpansion ex = (PlaceholderExpansion) i; if (ex.getRequiredPlugin() == null) { @@ -113,7 +109,6 @@ public class PlaceholderListener implements Listener { @EventHandler public void onQuit(PlayerQuitEvent e) { - Set expansions = PlaceholderAPI.getExpansions(); if (expansions.isEmpty()) { diff --git a/src/main/java/me/clip/placeholderapi/ServerLoadEventListener.java b/src/main/java/me/clip/placeholderapi/ServerLoadEventListener.java index 6bd38eb..0ad80cc 100644 --- a/src/main/java/me/clip/placeholderapi/ServerLoadEventListener.java +++ b/src/main/java/me/clip/placeholderapi/ServerLoadEventListener.java @@ -29,7 +29,7 @@ import java.util.Map; public class ServerLoadEventListener implements Listener { - private PlaceholderAPIPlugin plugin; + private final PlaceholderAPIPlugin plugin; public ServerLoadEventListener(PlaceholderAPIPlugin instance) { plugin = instance; @@ -50,6 +50,7 @@ public class ServerLoadEventListener implements Listener { plugin.getLogger().info("Placeholder expansion registration initializing..."); final Map alreadyRegistered = PlaceholderAPI.getPlaceholders(); plugin.getExpansionManager().registerAllExpansions(); + if (alreadyRegistered != null && !alreadyRegistered.isEmpty()) { alreadyRegistered.forEach(PlaceholderAPI::registerPlaceholderHook); } diff --git a/src/main/java/me/clip/placeholderapi/commands/ExpansionCloudCommands.java b/src/main/java/me/clip/placeholderapi/commands/ExpansionCloudCommands.java index db15f49..dc519d4 100644 --- a/src/main/java/me/clip/placeholderapi/commands/ExpansionCloudCommands.java +++ b/src/main/java/me/clip/placeholderapi/commands/ExpansionCloudCommands.java @@ -40,7 +40,7 @@ import static me.clip.placeholderapi.util.Msg.msg; public class ExpansionCloudCommands implements CommandExecutor { - private PlaceholderAPIPlugin plugin; + private final PlaceholderAPIPlugin plugin; public ExpansionCloudCommands(PlaceholderAPIPlugin instance) { plugin = instance; @@ -76,22 +76,24 @@ public class ExpansionCloudCommands implements CommandExecutor { msg(s, "&aRefresh task started. Use &f/papi ecloud list all &ain a few!!"); plugin.getExpansionCloud().clean(); plugin.getExpansionCloud().fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions()); + return true; } if (plugin.getExpansionCloud().getCloudExpansions().isEmpty()) { msg(s, "&7No cloud expansions are available at this time."); + return true; } if (args[1].equalsIgnoreCase("clear")) { - plugin.getExpansionCloud().clean(); msg(s, "&aThe cache has been cleared!!"); + plugin.getExpansionCloud().clean(); + return true; } if (args[1].equalsIgnoreCase("status")) { - msg(s, "&bThere are &f" + plugin.getExpansionCloud().getCloudExpansions().size() + " &bexpansions available on the cloud.", "&7A total of &f" + plugin.getExpansionCloud().getCloudAuthorCount() @@ -105,9 +107,9 @@ public class ExpansionCloudCommands implements CommandExecutor { } if (args[1].equalsIgnoreCase("info")) { - if (args.length < 3) { msg(s, "&cAn expansion name must be specified!"); + return true; } @@ -115,6 +117,7 @@ public class ExpansionCloudCommands implements CommandExecutor { if (expansion == null) { msg(s, "&cNo expansion found by the name: &f" + args[2]); + return true; } @@ -122,6 +125,7 @@ public class ExpansionCloudCommands implements CommandExecutor { msg(s, (expansion.shouldUpdate() ? "&e" : "") + expansion.getName() + " &8&m-- &r" + expansion .getVersion().getUrl()); + return true; } @@ -160,21 +164,18 @@ public class ExpansionCloudCommands implements CommandExecutor { } if (args[1].equalsIgnoreCase("versioninfo")) { - if (args.length < 4) { msg(s, "&cAn expansion name and version must be specified!"); return true; } CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(args[2]); - if (expansion == null) { msg(s, "&cNo expansion found by the name: &f" + args[2]); return true; } CloudExpansion.Version version = expansion.getVersion(args[3]); - if (version == null) { msg(s, "&cThe version specified does not exist for expansion: &f" + expansion.getName()); return true; @@ -195,29 +196,30 @@ public class ExpansionCloudCommands implements CommandExecutor { download.suggestCommand( "/papi ecloud download " + expansion.getName() + " " + version.getVersion()); download.send(p); + return true; } if (args[1].equalsIgnoreCase("placeholders")) { - if (args.length < 3) { msg(s, "&cAn expansion name must be specified!"); + return true; } CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(args[2]); - if (expansion == null) { msg(s, "&cNo expansion found by the name: &f" + args[2]); + return true; } List placeholders = expansion.getPlaceholders(); - if (placeholders == null) { msg(s, "&cThe expansion: &f" + expansion.getName() + " &cdoes not have any placeholders listed.", "&7You should contact &f" + expansion.getAuthor() + " &7and ask for them to be added."); + return true; } @@ -225,6 +227,7 @@ public class ExpansionCloudCommands implements CommandExecutor { || plugin.getExpansionManager().getRegisteredExpansion(expansion.getName()) == null) { msg(s, "&bPlaceholders: &f" + placeholders.size(), String.join("&a, &f", placeholders)); + return true; } @@ -242,11 +245,11 @@ public class ExpansionCloudCommands implements CommandExecutor { } message.send(p); + return true; } if (args[1].equalsIgnoreCase("list")) { - int page = 1; String author; @@ -271,17 +274,18 @@ public class ExpansionCloudCommands implements CommandExecutor { page = Integer.parseInt(args[3]); } catch (NumberFormatException ex) { msg(s, "&cPage number must be an integer!"); + return true; } } if (page < 1) { msg(s, "&cPage must be greater than or equal to 1!"); + return true; } int avail; - Map ex; if (installed) { @@ -294,14 +298,15 @@ public class ExpansionCloudCommands implements CommandExecutor { if (ex == null || ex.isEmpty()) { msg(s, "&cNo expansions available" + (author != null ? " for author &f" + author : "")); + return true; } avail = plugin.getExpansionCloud().getPagesAvailable(ex, 10); - if (page > avail) { msg(s, "&cThere " + ((avail == 1) ? " is only &f" + avail + " &cpage available!" : "are only &f" + avail + " &cpages available!")); + return true; } @@ -313,6 +318,7 @@ public class ExpansionCloudCommands implements CommandExecutor { if (ex == null) { msg(s, "&cThere was a problem getting the requested page..."); + return true; } @@ -321,19 +327,26 @@ public class ExpansionCloudCommands implements CommandExecutor { if (!(s instanceof Player)) { Map expansions = new HashMap<>(); + for (CloudExpansion exp : ex.values()) { if (exp == null || exp.getName() == null) { continue; } + expansions.put(exp.getName(), exp); } + List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); + int i = (int) ex.keySet().toArray()[0]; + for (String name : ce) { if (expansions.get(name) == null) { continue; } + CloudExpansion expansion = expansions.get(name); + msg(s, "&b" + i + "&7: " + (expansion.shouldUpdate() ? "&6" : (expansion.hasExpansion() ? "&a" : "&7")) + expansion @@ -347,20 +360,27 @@ public class ExpansionCloudCommands implements CommandExecutor { Player p = (Player) s; Map expansions = new HashMap<>(); + for (CloudExpansion exp : ex.values()) { if (exp == null || exp.getName() == null) { continue; } + expansions.put(exp.getName(), exp); } + List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); + int i = page > 1 ? page * 10 : 0; + for (String name : ce) { if (expansions.get(name) == null) { continue; } + CloudExpansion expansion = expansions.get(name); StringBuilder sb = new StringBuilder(); + if (expansion.shouldUpdate()) { sb.append("&6Click to update to the latest version of this expansion\n\n"); } else if (!expansion.hasExpansion()) { @@ -368,12 +388,12 @@ public class ExpansionCloudCommands implements CommandExecutor { } else { sb.append("&aYou have the latest version of this expansion\n\n"); } - sb.append("&bAuthor&7: &f" + expansion.getAuthor() + "\n"); - sb.append("&bVerified&7: &f" + expansion.isVerified() + "\n"); - sb.append("&bLatest version&7: &f" + expansion.getVersion().getVersion() + "\n"); - sb.append( - "&bLast updated&7: &f" + expansion.getTimeSinceLastUpdate() + " ago\n"); - sb.append("\n" + expansion.getDescription()); + + sb.append("&bAuthor&7: &f").append(expansion.getAuthor()).append("\n"); + sb.append("&bVerified&7: &f").append(expansion.isVerified()).append("\n"); + sb.append("&bLatest version&7: &f").append(expansion.getVersion().getVersion()).append("\n"); + sb.append("&bLast updated&7: &f").append(expansion.getTimeSinceLastUpdate()).append(" ago\n"); + sb.append("\n").append(expansion.getDescription()); String msg = color( "&b" + (i + 1) + "&7: " + (expansion.shouldUpdate() ? "&6" @@ -383,34 +403,33 @@ public class ExpansionCloudCommands implements CommandExecutor { JSONMessage line = JSONMessage.create(msg); line.tooltip(hover); + if (expansion.shouldUpdate() || !expansion.hasExpansion()) { line.suggestCommand("/papi ecloud download " + expansion.getName()); - } - else { + } else { line.suggestCommand("/papi ecloud info " + expansion.getName()); } + line.send(p); i++; } + return true; } if (args[1].equalsIgnoreCase("download")) { - if (args.length < 3) { msg(s, "&cAn expansion name must be specified!"); return true; } CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(args[2]); - if (expansion == null) { msg(s, "&cNo expansion found with the name: &f" + args[2]); return true; } PlaceholderExpansion loaded = plugin.getExpansionManager().getRegisteredExpansion(args[2]); - if (loaded != null && loaded.isRegistered()) { PlaceholderAPI.unregisterPlaceholderHook(loaded.getIdentifier()); } @@ -423,20 +442,22 @@ public class ExpansionCloudCommands implements CommandExecutor { msg(s, "&cThe version you specified does not exist for &f" + expansion.getName()); msg(s, "&7Available versions: &f" + expansion.getVersions().size()); msg(s, String.join("&a, &f", expansion.getAvailableVersions())); + return true; } } - msg(s, "&aDownload starting for expansion: &f" + expansion.getName() + " &aversion: &f" - + version); + msg(s, "&aDownload starting for expansion: &f" + expansion.getName() + " &aversion: &f" + version); String player = ((s instanceof Player) ? s.getName() : null); plugin.getExpansionCloud().downloadExpansion(player, expansion, version); plugin.getExpansionCloud().clean(); plugin.getExpansionCloud().fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions()); + return true; } msg(s, "&cIncorrect usage! &b/papi ecloud"); + return true; } diff --git a/src/main/java/me/clip/placeholderapi/commands/PlaceholderAPICommands.java b/src/main/java/me/clip/placeholderapi/commands/PlaceholderAPICommands.java index 479781a..be3639e 100644 --- a/src/main/java/me/clip/placeholderapi/commands/PlaceholderAPICommands.java +++ b/src/main/java/me/clip/placeholderapi/commands/PlaceholderAPICommands.java @@ -37,8 +37,8 @@ import java.util.stream.Collectors; public class PlaceholderAPICommands implements CommandExecutor { - private PlaceholderAPIPlugin plugin; - private CommandExecutor eCloud; + private final PlaceholderAPIPlugin plugin; + private final CommandExecutor eCloud; public PlaceholderAPICommands(PlaceholderAPIPlugin i) { plugin = i; @@ -53,9 +53,9 @@ public class PlaceholderAPICommands implements CommandExecutor { "&fCreated by&7: &b" + plugin.getDescription().getAuthors(), "&fPapi commands: &b/papi help", "&fEcloud commands: &b/papi ecloud"); + return true; } else { - if (args[0].equalsIgnoreCase("help")) { Msg.msg(s, "PlaceholderAPI &aHelp &e(&f" + plugin.getDescription().getVersion() + "&e)", @@ -77,6 +77,7 @@ public class PlaceholderAPICommands implements CommandExecutor { "&fUnregister an expansion by name", "&b/papi reload", "&fReload the config settings"); + if (s.hasPermission("placeholderapi.ecloud")) { if (plugin.getExpansionCloud() == null) { Msg.msg(s, "&b/papi enablecloud", @@ -88,88 +89,113 @@ public class PlaceholderAPICommands implements CommandExecutor { "&fView ecloud command usage"); } } + return true; } else if (args[0].equalsIgnoreCase("ecloud")) { - if (!s.hasPermission("placeholderapi.ecloud")) { Msg.msg(s, "&cYou don't have permission to do that!"); + return true; } + if (plugin.getExpansionCloud() == null) { Msg.msg(s, "&7The expansion cloud is not enabled!"); + return true; } + return eCloud.onCommand(s, c, label, args); } else if (args[0].equalsIgnoreCase("enablecloud")) { - if (!s.hasPermission("placeholderapi.ecloud")) { Msg.msg(s, "&cYou don't have permission to do that!"); + return true; } + if (plugin.getExpansionCloud() != null) { Msg.msg(s, "&7The cloud is already enabled!"); + return true; } + plugin.enableCloud(); plugin.getPlaceholderAPIConfig().setCloudEnabled(true); Msg.msg(s, "&aThe cloud has been enabled!"); + return true; } else if (args[0].equalsIgnoreCase("disablecloud")) { - if (!s.hasPermission("placeholderapi.ecloud")) { Msg.msg(s, "&cYou don't have permission to do that!"); + return true; } + if (plugin.getExpansionCloud() == null) { Msg.msg(s, "&7The cloud is already disabled!"); + return true; } + plugin.disableCloud(); plugin.getPlaceholderAPIConfig().setCloudEnabled(false); Msg.msg(s, "&aThe cloud has been disabled!"); + return true; } else if (args.length > 1 && args[0].equalsIgnoreCase("info")) { - if (!s.hasPermission("placeholderapi.info")) { Msg.msg(s, "&cYou don't have permission to do that!"); + return true; } + PlaceholderExpansion ex = plugin.getExpansionManager().getRegisteredExpansion(args[1]); if (ex == null) { Msg.msg(s, "&cThere is no expansion loaded with the identifier: &f" + args[1]); + return true; } + Msg.msg(s, "&7Placeholder expansion info for: &f" + ex.getName()); Msg.msg(s, "&7Status: " + (ex.isRegistered() ? "&aRegistered" : "&cNot registered")); + if (ex.getAuthor() != null) { Msg.msg(s, "&7Created by: &f" + ex.getAuthor()); } + if (ex.getVersion() != null) { Msg.msg(s, "&7Version: &f" + ex.getVersion()); } + if (ex.getRequiredPlugin() != null) { Msg.msg(s, "&7Requires plugin: &f" + ex.getRequiredPlugin()); } + if (ex.getPlaceholders() != null) { Msg.msg(s, "&8&m-- &r&7Placeholders &8&m--"); + for (String placeholder : ex.getPlaceholders()) { Msg.msg(s, placeholder); } } + return true; } else if (args.length > 2 && args[0].equalsIgnoreCase("parse") || args.length > 2 && args[0].equalsIgnoreCase("bcparse")) { if (!s.hasPermission("placeholderapi.parse")) { Msg.msg(s, "&cYou don't have permission to do that!"); + return true; } - OfflinePlayer pl = null; + + OfflinePlayer pl; + if (args[1].equalsIgnoreCase("me")) { if (s instanceof Player) { pl = (Player) s; } else { Msg.msg(s, "&cThis command must target a player when used by console"); + return true; } } else { @@ -179,56 +205,67 @@ public class PlaceholderAPICommands implements CommandExecutor { pl = Bukkit.getOfflinePlayer(args[1]); } } + if (pl == null || !pl.hasPlayedBefore()) { Msg.msg(s, "&cFailed to find player: &f" + args[1]); return true; } + String parse = StringUtils.join(args, " ", 2, args.length); + if (args[0].equalsIgnoreCase("bcparse")) { Msg.broadcast("&r" + PlaceholderAPI.setPlaceholders(pl, parse)); } else { Msg.msg(s, "&r" + PlaceholderAPI.setPlaceholders(pl, parse)); } + return true; } else if (args.length > 3 && args[0].equalsIgnoreCase("parserel")) { - if (!(s instanceof Player)) { Msg.msg(s, "&cThis command can only be used in game!"); + return true; } else { if (!s.hasPermission("placeholderapi.parse")) { Msg.msg(s, "&cYou don't have permission to do that!"); + return true; } } Player one = Bukkit.getPlayer(args[1]); if (one == null) { Msg.msg(s, args[1] + " &cis not online!"); + return true; } + Player two = Bukkit.getPlayer(args[2]); if (two == null) { Msg.msg(s, args[2] + " &cis not online!"); + return true; } + String parse = StringUtils.join(args, " ", 3, args.length); Msg.msg(s, "&r" + PlaceholderAPI.setRelationalPlaceholders(one, two, parse)); + return true; } else if (args[0].equalsIgnoreCase("reload")) { - if (s instanceof Player) { if (!s.hasPermission("placeholderapi.reload")) { Msg.msg(s, "&cYou don't have permission to do that!"); + return true; } } + Msg.msg(s, "&fPlaceholder&7API &bconfiguration reloaded!"); plugin.reloadConf(s); } else if (args[0].equalsIgnoreCase("list")) { - if (s instanceof Player) { if (!s.hasPermission("placeholderapi.list")) { Msg.msg(s, "&cYou don't have permission to do that!"); + return true; } } @@ -236,15 +273,17 @@ public class PlaceholderAPICommands implements CommandExecutor { Set registered = PlaceholderAPI.getRegisteredIdentifiers(); if (registered.isEmpty()) { Msg.msg(s, "&7There are no placeholder hooks currently registered!"); + return true; } + Msg.msg(s, registered.size() + " &7Placeholder hooks registered:"); Msg.msg(s, registered.stream().sorted().collect(Collectors.joining(", "))); } else if (args.length > 1 && args[0].equalsIgnoreCase("register")) { - if (s instanceof Player) { if (!s.hasPermission("placeholderapi.register")) { Msg.msg(s, "&cYou don't have permission to do that!"); + return true; } } @@ -254,6 +293,7 @@ public class PlaceholderAPICommands implements CommandExecutor { if (ex == null) { Msg.msg(s, "&cFailed to register expansion from " + fileName); + return true; } @@ -263,14 +303,15 @@ public class PlaceholderAPICommands implements CommandExecutor { if (s instanceof Player) { if (!s.hasPermission("placeholderapi.register")) { Msg.msg(s, "&cYou don't have permission to do that!"); + return true; } } PlaceholderExpansion ex = plugin.getExpansionManager().getRegisteredExpansion(args[1]); - if (ex == null) { Msg.msg(s, "&cFailed to find expansion: &f" + args[1]); + return true; } @@ -284,6 +325,7 @@ public class PlaceholderAPICommands implements CommandExecutor { Msg.msg(s, "&cIncorrect usage! &7/papi help"); } } + return true; } diff --git a/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java b/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java index 08da615..8c66bce 100644 --- a/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java +++ b/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java @@ -24,7 +24,7 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin; public class PlaceholderAPIConfig { - private PlaceholderAPIPlugin plugin; + private final PlaceholderAPIPlugin plugin; public PlaceholderAPIConfig(PlaceholderAPIPlugin i) { plugin = i; diff --git a/src/main/java/me/clip/placeholderapi/events/ExpansionRegisterEvent.java b/src/main/java/me/clip/placeholderapi/events/ExpansionRegisterEvent.java index 9bdff16..f493bd6 100644 --- a/src/main/java/me/clip/placeholderapi/events/ExpansionRegisterEvent.java +++ b/src/main/java/me/clip/placeholderapi/events/ExpansionRegisterEvent.java @@ -28,9 +28,10 @@ import org.bukkit.event.HandlerList; public class ExpansionRegisterEvent extends Event implements Cancellable { private static final HandlerList HANDLERS = new HandlerList(); - private PlaceholderExpansion expansion; + private final PlaceholderExpansion expansion; private boolean isCancelled; + public ExpansionRegisterEvent(PlaceholderExpansion expansion) { this.expansion = expansion; } diff --git a/src/main/java/me/clip/placeholderapi/events/ExpansionUnregisterEvent.java b/src/main/java/me/clip/placeholderapi/events/ExpansionUnregisterEvent.java index 7682f78..de33feb 100644 --- a/src/main/java/me/clip/placeholderapi/events/ExpansionUnregisterEvent.java +++ b/src/main/java/me/clip/placeholderapi/events/ExpansionUnregisterEvent.java @@ -27,7 +27,7 @@ import org.bukkit.event.HandlerList; public class ExpansionUnregisterEvent extends Event { private static final HandlerList HANDLERS = new HandlerList(); - private PlaceholderExpansion expansion; + private final PlaceholderExpansion expansion; public ExpansionUnregisterEvent(PlaceholderExpansion expansion) { this.expansion = expansion; diff --git a/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java b/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java index 68f7539..a75941b 100644 --- a/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java +++ b/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java @@ -28,8 +28,8 @@ import org.bukkit.event.HandlerList; public class PlaceholderHookUnloadEvent extends Event { private static final HandlerList HANDLERS = new HandlerList(); - private String plugin; - private PlaceholderHook hook; + private final String plugin; + private final PlaceholderHook hook; public PlaceholderHookUnloadEvent(String plugin, PlaceholderHook placeholderHook) { this.plugin = plugin; diff --git a/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java b/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java index 9b3ac70..3c82471 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java @@ -36,10 +36,11 @@ import java.util.Map; import java.util.Map.Entry; public final class ExpansionManager { - private PlaceholderAPIPlugin plugin; + private final PlaceholderAPIPlugin plugin; public ExpansionManager(PlaceholderAPIPlugin instance) { plugin = instance; + File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), "expansions"); if (!f.exists()) { f.mkdirs(); @@ -54,6 +55,7 @@ public final class ExpansionManager { } } } + return null; } @@ -61,16 +63,19 @@ public final class ExpansionManager { if (expansion == null || expansion.getIdentifier() == null) { return false; } + if (expansion instanceof Configurable) { Map defaults = ((Configurable) expansion).getDefaults(); String pre = "expansions." + expansion.getIdentifier() + "."; FileConfiguration cfg = plugin.getConfig(); boolean save = false; + if (defaults != null) { for (Entry entries : defaults.entrySet()) { if (entries.getKey() == null || entries.getKey().isEmpty()) { continue; } + if (entries.getValue() == null) { if (cfg.contains(pre + entries.getKey())) { save = true; @@ -84,11 +89,13 @@ public final class ExpansionManager { } } } + if (save) { plugin.saveConfig(); plugin.reloadConfig(); } } + if (expansion instanceof VersionSpecific) { VersionSpecific nms = (VersionSpecific) expansion; if (!nms.isCompatibleWith(PlaceholderAPIPlugin.getServerVersion())) { @@ -99,22 +106,29 @@ public final class ExpansionManager { return false; } } + if (!expansion.canRegister()) { return false; } + if (!expansion.register()) { return false; } + if (expansion instanceof Listener) { Listener l = (Listener) expansion; Bukkit.getPluginManager().registerEvents(l, plugin); } + plugin.getLogger().info("Successfully registered expansion: " + expansion.getIdentifier()); + if (expansion instanceof Taskable) { ((Taskable) expansion).start(); } + if (plugin.getExpansionCloud() != null) { CloudExpansion ce = plugin.getExpansionCloud().getCloudExpansion(expansion.getIdentifier()); + if (ce != null) { ce.setHasExpansion(true); if (!ce.getLatestVersion().equals(expansion.getVersion())) { @@ -122,6 +136,7 @@ public final class ExpansionManager { } } } + return true; } @@ -131,12 +146,14 @@ public final class ExpansionManager { if (subs == null || subs.isEmpty()) { return null; } + // only register the first instance found as an expansion jar should only have 1 class // extending PlaceholderExpansion PlaceholderExpansion ex = createInstance(subs.get(0)); if (registerExpansion(ex)) { return ex; } + return null; } @@ -144,10 +161,12 @@ public final class ExpansionManager { if (plugin == null) { return; } + List> subs = FileUtil.getClasses("expansions", null, PlaceholderExpansion.class); if (subs == null || subs.isEmpty()) { return; } + for (Class klass : subs) { PlaceholderExpansion ex = createInstance(klass); if (ex != null) { @@ -160,10 +179,12 @@ public final class ExpansionManager { if (klass == null) { return null; } + PlaceholderExpansion ex = null; if (!PlaceholderExpansion.class.isAssignableFrom(klass)) { return null; } + try { Constructor[] c = klass.getConstructors(); if (c.length == 0) { @@ -181,6 +202,7 @@ public final class ExpansionManager { .severe("Failed to init placeholder expansion from class: " + klass.getName()); plugin.getLogger().severe(t.getMessage()); } + return ex; } } diff --git a/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java b/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java index 88b85cd..74cfc38 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java @@ -39,7 +39,7 @@ public enum NMSVersion { SPIGOT_1_13_R2("v1_13_R2"), SPIGOT_1_14_R1("v1_14_R1"); - private String version; + private final String version; NMSVersion(String version) { this.version = version; @@ -51,6 +51,7 @@ public enum NMSVersion { return v; } } + return NMSVersion.UNKNOWN; } diff --git a/src/main/java/me/clip/placeholderapi/expansion/Version.java b/src/main/java/me/clip/placeholderapi/expansion/Version.java index 1d9646f..a27345f 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Version.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Version.java @@ -22,9 +22,8 @@ package me.clip.placeholderapi.expansion; public final class Version { - private boolean isSpigot; - - private String version; + private final boolean isSpigot; + private final String version; public Version(String version, boolean isSpigot) { this.version = version; diff --git a/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java b/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java index 49a4e73..4e2ee0a 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java @@ -173,7 +173,6 @@ public class CloudExpansion { } public class Version { - private String url, version, release_notes; public String getUrl() { diff --git a/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java b/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java index 16ec742..029e846 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java @@ -129,16 +129,19 @@ public class ExpansionCloudManager { if (map == null) { return 0; } + int pages = map.size() > 0 ? 1 : 0; if (pages == 0) { return pages; } + if (map.size() > amount) { pages = map.size() / amount; if (map.size() % amount > 0) { pages++; } } + return pages; } @@ -158,7 +161,6 @@ public class ExpansionCloudManager { public void fetch(boolean allowUnverified) { - plugin.getLogger().info("Fetching available expansion information..."); plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> { @@ -170,7 +172,6 @@ public class ExpansionCloudManager { final List unsorted = new ArrayList<>(); data.forEach((name, cexp) -> { - if ((allowUnverified || cexp.isVerified()) && cexp.getLatestVersion() != null && cexp.getVersion(cexp.getLatestVersion()) != null) { cexp.setName(name); @@ -201,7 +202,6 @@ public class ExpansionCloudManager { if (updates > 0) { plugin.getLogger().info(updates + " installed expansions have updates available."); } - }); } @@ -211,13 +211,11 @@ public class ExpansionCloudManager { } private void download(URL url, String name) throws IOException { - InputStream is = null; FileOutputStream fos = null; try { - URLConnection urlConn = url.openConnection(); is = urlConn.getInputStream(); @@ -251,7 +249,6 @@ public class ExpansionCloudManager { } public void downloadExpansion(final String player, final CloudExpansion ex, final String version) { - if (downloading.contains(ex.getName())) { return; } @@ -273,13 +270,11 @@ public class ExpansionCloudManager { Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { try { - download(new URL(ver.getUrl()), ex.getName()); plugin.getLogger().info("Download of expansion: " + ex.getName() + " complete!"); } catch (Exception e) { - plugin.getLogger() .warning("Failed to download expansion: " + ex.getName() + " from: " + ver.getUrl()); @@ -300,11 +295,9 @@ public class ExpansionCloudManager { } Bukkit.getScheduler().runTask(plugin, () -> { - downloading.remove(ex.getName()); if (player != null) { - Player p = Bukkit.getPlayer(player); if (p != null) { @@ -319,16 +312,15 @@ public class ExpansionCloudManager { private static class URLReader { - static String read(String url) { StringBuilder builder = new StringBuilder(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(url).openStream()))) { - String inputLine; while ((inputLine = reader.readLine()) != null) { builder.append(inputLine); } + } catch (Exception ex) { builder.setLength(0); } diff --git a/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java b/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java index 26e125e..b02fbbb 100644 --- a/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java +++ b/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java @@ -28,9 +28,8 @@ import org.bukkit.plugin.Plugin; @Deprecated public abstract class EZPlaceholderHook extends PlaceholderHook { - private String identifier; - - private String plugin; + private final String identifier; + private final String plugin; public EZPlaceholderHook(Plugin plugin, String identifier) { Validate.notNull(plugin, "Plugin can not be null!"); diff --git a/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java b/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java index c814c59..f3f56af 100644 --- a/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java +++ b/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java @@ -36,8 +36,9 @@ import java.net.URL; public class UpdateChecker implements Listener { private final int RESOURCE_ID = 6245; - private PlaceholderAPIPlugin plugin; - private String spigotVersion, pluginVersion; + private final PlaceholderAPIPlugin plugin; + private String spigotVersion; + private final String pluginVersion; private boolean updateAvailable; public UpdateChecker(PlaceholderAPIPlugin i) { @@ -86,9 +87,10 @@ public class UpdateChecker implements Listener { } private boolean spigotIsNewer() { - if (spigotVersion == null || spigotVersion.isEmpty()) { - return false; - } + if (spigotVersion == null || spigotVersion.isEmpty()) { + return false; + } + String plV = toReadable(pluginVersion); String spV = toReadable(spigotVersion); return plV.compareTo(spV) < 0; @@ -98,6 +100,7 @@ public class UpdateChecker implements Listener { if (version.contains("-DEV-")) { version = version.split("-DEV-")[0]; } + return version.replaceAll("\\.", ""); } diff --git a/src/main/java/me/clip/placeholderapi/util/FileUtil.java b/src/main/java/me/clip/placeholderapi/util/FileUtil.java index ee5014d..0660337 100644 --- a/src/main/java/me/clip/placeholderapi/util/FileUtil.java +++ b/src/main/java/me/clip/placeholderapi/util/FileUtil.java @@ -39,28 +39,35 @@ public class FileUtil { public static List> getClasses(String folder, String fileName, Class type) { List> list = new ArrayList<>(); + try { File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), folder); if (!f.exists()) { return list; } + FilenameFilter fileNameFilter = (dir, name) -> { if (fileName != null) { return name.endsWith(".jar") && name.replace(".jar", "") .equalsIgnoreCase(fileName.replace(".jar", "")); } + return name.endsWith(".jar"); }; + File[] jars = f.listFiles(fileNameFilter); if (jars == null) { return list; } + for (File file : jars) { list = gather(file.toURI().toURL(), list, type); } + return list; } catch (Throwable t) { } + return null; } @@ -68,19 +75,25 @@ public class FileUtil { if (list == null) { list = new ArrayList<>(); } - try (URLClassLoader cl = new URLClassLoader(new URL[]{jar}, clazz.getClassLoader()); JarInputStream jis = new JarInputStream(jar.openStream())) { + + try (URLClassLoader cl = new URLClassLoader(new URL[]{jar}, clazz.getClassLoader()); + JarInputStream jis = new JarInputStream(jar.openStream())) { + while (true) { JarEntry j = jis.getNextJarEntry(); if (j == null) { break; } + String name = j.getName(); if (name == null || name.isEmpty()) { continue; } + if (name.endsWith(".class")) { name = name.replace("/", "."); String cname = name.substring(0, name.lastIndexOf(".class")); + Class c = cl.loadClass(cname); if (clazz.isAssignableFrom(c)) { list.add(c); @@ -89,6 +102,7 @@ public class FileUtil { } } catch (Throwable t) { } + return list; } } diff --git a/src/main/java/me/clip/placeholderapi/util/TimeFormat.java b/src/main/java/me/clip/placeholderapi/util/TimeFormat.java index facce5b..a338efc 100644 --- a/src/main/java/me/clip/placeholderapi/util/TimeFormat.java +++ b/src/main/java/me/clip/placeholderapi/util/TimeFormat.java @@ -21,7 +21,6 @@ package me.clip.placeholderapi.util; public enum TimeFormat { - DAYS, HOURS, MINUTES, diff --git a/src/main/java/me/clip/placeholderapi/util/TimeUtil.java b/src/main/java/me/clip/placeholderapi/util/TimeUtil.java index 802055d..e076c67 100644 --- a/src/main/java/me/clip/placeholderapi/util/TimeUtil.java +++ b/src/main/java/me/clip/placeholderapi/util/TimeUtil.java @@ -23,7 +23,6 @@ package me.clip.placeholderapi.util; public class TimeUtil { public static String getRemaining(int seconds, TimeFormat type) { - if (seconds < 60) { switch (type) { case DAYS: @@ -33,12 +32,14 @@ public class TimeUtil { case SECONDS: return String.valueOf(seconds); } + return String.valueOf(seconds); } int minutes = seconds / 60; int s = 60 * minutes; int secondsLeft = seconds - s; + if (minutes < 60) { switch (type) { case DAYS: @@ -49,6 +50,7 @@ public class TimeUtil { case SECONDS: return String.valueOf(secondsLeft); } + return String.valueOf(seconds); } @@ -56,6 +58,7 @@ public class TimeUtil { int hours = minutes / 60; int inMins = 60 * hours; int leftOver = minutes - inMins; + switch (type) { case DAYS: return "0"; @@ -66,6 +69,7 @@ public class TimeUtil { case SECONDS: return String.valueOf(secondsLeft); } + return String.valueOf(seconds); } @@ -84,12 +88,14 @@ public class TimeUtil { case SECONDS: return String.valueOf(secondsLeft); } + return String.valueOf(seconds); } else { int hours = leftOver / 60; int hoursInMins = 60 * hours; int minsLeft = leftOver - hoursInMins; + switch (type) { case DAYS: return String.valueOf(days); @@ -100,6 +106,7 @@ public class TimeUtil { case SECONDS: return String.valueOf(secondsLeft); } + return String.valueOf(seconds); } } @@ -113,6 +120,7 @@ public class TimeUtil { int minutes = seconds / 60; int s = 60 * minutes; int secondsLeft = seconds - s; + if (minutes < 60) { if (secondsLeft > 0) { return minutes + "m " + secondsLeft + "s"; @@ -120,18 +128,22 @@ public class TimeUtil { return minutes + "m"; } } + if (minutes < 1440) { String time; int hours = minutes / 60; time = hours + "h"; int inMins = 60 * hours; int leftOver = minutes - inMins; + if (leftOver >= 1) { time = time + " " + leftOver + "m"; } + if (secondsLeft > 0) { time = time + " " + secondsLeft + "s"; } + return time; } @@ -140,20 +152,24 @@ public class TimeUtil { time = days + "d"; int inMins = 1440 * days; int leftOver = minutes - inMins; + if (leftOver >= 1) { if (leftOver < 60) { time = time + " " + leftOver + "m"; } else { int hours = leftOver / 60; time = time + " " + hours + "h"; + int hoursInMins = 60 * hours; int minsLeft = leftOver - hoursInMins; time = time + " " + minsLeft + "m"; } } + if (secondsLeft > 0) { time = time + " " + secondsLeft + "s"; } + return time; } }