diff --git a/.gitignore b/.gitignore index d6ee8a7..1f79a85 100644 --- a/.gitignore +++ b/.gitignore @@ -51,10 +51,10 @@ local.properties .worksheet ### Eclipse Patch ### -# Eclipse Core +# Eclipse Core .project -# JDT-specific (Eclipse Java Development Tools) +# JDT-specific (Eclipse Java Development Tools) .classpath ### Intellij ### @@ -143,4 +143,4 @@ nbbuild/ dist/ nbdist/ .nb-gradle/ -nbactions.xml +nbactions.xml \ No newline at end of file diff --git a/README.md b/README.md index f512b33..192c91a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,18 @@ # PlaceholderAPI -A placeholder plugin -[![Build Status](http://ci.extendedclip.com/buildStatus/icon?job=PlaceholderAPI)](http://ci.extendedclip.com/job/PlaceholderAPI/) \ No newline at end of file + +PlaceholderAPI is a library that allows servers to use placeholders from a wide range of your favorite plugins, such as +Essentials, Factions, LuckPerms, Vault, AutoSell, GriefPrevention, and many more! +You can display information from your favorite plugins in any plugin that supports PlaceholderAPI. +Through the use of the Expansion cloud, PAPI effectively and efficiently allows you to pick and choose which placeholders you want to install. +The Expansion cloud allows you to receive new placeholders, updates to existing placeholder expansions, and much more directly from your server +without updating the actual plugin. With over 100,000 downloads, PlaceholderAPI is a must have for a server of any type or scale. + +[![Build Status](http://ci.extendedclip.com/buildStatus/icon?job=PlaceholderAPI)](http://ci.extendedclip.com/job/PlaceholderAPI/) + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 076b7d3..32a0e8a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 2.8.5 PlaceholderAPI - An awesome placeholder plugin + An awesome placeholder provider! http://extendedclip.com @@ -22,6 +22,10 @@ sonatype https://oss.sonatype.org/content/repositories/snapshots/ + + bstats-repo + http://repo.bstats.org/content/repositories/releases/ + @@ -31,6 +35,12 @@ 1.12.2-R0.1-SNAPSHOT provided + + org.bstats + bstats-bukkit + 1.2 + compile + @@ -57,6 +67,13 @@ true + false + + + org.bstats + me.clip.placeholderapi.metrics + + diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java index 40410a7..e759270 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java @@ -20,25 +20,19 @@ */ package me.clip.placeholderapi; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import me.clip.placeholderapi.events.PlaceholderHookUnloadEvent; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.Relational; - import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class PlaceholderAPI { private PlaceholderAPI() { diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java index 83e4700..a659813 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java @@ -20,12 +20,6 @@ */ package me.clip.placeholderapi; -import java.text.SimpleDateFormat; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.TimeUnit; - import me.clip.placeholderapi.configuration.PlaceholderAPIConfig; import me.clip.placeholderapi.expansion.ExpansionManager; import me.clip.placeholderapi.expansion.PlaceholderExpansion; @@ -33,13 +27,17 @@ import me.clip.placeholderapi.expansion.Version; import me.clip.placeholderapi.expansion.cloud.ExpansionCloudManager; import me.clip.placeholderapi.updatechecker.UpdateChecker; import me.clip.placeholderapi.util.TimeUtil; -import me.clip.placeholderapi.metrics.Metrics; - +import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.plugin.java.JavaPlugin; +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + /** * Yes I have a shit load of work to do... @@ -109,7 +107,6 @@ public class PlaceholderAPIPlugin extends JavaPlugin { expansionManager.clean(); PlaceholderAPI.unregisterAllExpansions(); reloadConfig(); - saveConfig(); setupOptions(); expansionManager.registerAllExpansions(); if (!config.isCloudEnabled()) { diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderListener.java b/src/main/java/me/clip/placeholderapi/PlaceholderListener.java index c383d31..03e0778 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderListener.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderListener.java @@ -20,18 +20,10 @@ */ package me.clip.placeholderapi; -import java.util.Map; -import java.util.Map.Entry; - import me.clip.placeholderapi.events.PlaceholderHookUnloadEvent; -import me.clip.placeholderapi.expansion.Cacheable; -import me.clip.placeholderapi.expansion.Cleanable; -import me.clip.placeholderapi.expansion.ExpansionManager; -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import me.clip.placeholderapi.expansion.Taskable; +import me.clip.placeholderapi.expansion.*; import me.clip.placeholderapi.expansion.cloud.CloudExpansion; import me.clip.placeholderapi.external.EZPlaceholderHook; - import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -41,6 +33,9 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.event.server.PluginEnableEvent; +import java.util.Map; +import java.util.Map.Entry; + @SuppressWarnings("deprecation") public class PlaceholderListener implements Listener { diff --git a/src/main/java/me/clip/placeholderapi/commands/bukkit/ExpansionCloudCommands.java b/src/main/java/me/clip/placeholderapi/commands/bukkit/ExpansionCloudCommands.java index fcdaba5..89ba2c3 100644 --- a/src/main/java/me/clip/placeholderapi/commands/bukkit/ExpansionCloudCommands.java +++ b/src/main/java/me/clip/placeholderapi/commands/bukkit/ExpansionCloudCommands.java @@ -20,20 +20,19 @@ */ package me.clip.placeholderapi.commands.bukkit; -import java.util.Map; -import java.util.Map.Entry; - import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.cloud.CloudExpansion; import me.clip.placeholderapi.util.Msg; - import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import java.util.Map; +import java.util.Map.Entry; + public class ExpansionCloudCommands implements CommandExecutor { private PlaceholderAPIPlugin plugin; diff --git a/src/main/java/me/clip/placeholderapi/commands/bukkit/PlaceholderAPICommands.java b/src/main/java/me/clip/placeholderapi/commands/bukkit/PlaceholderAPICommands.java index b3b612b..6e0a51c 100644 --- a/src/main/java/me/clip/placeholderapi/commands/bukkit/PlaceholderAPICommands.java +++ b/src/main/java/me/clip/placeholderapi/commands/bukkit/PlaceholderAPICommands.java @@ -20,19 +20,18 @@ */ package me.clip.placeholderapi.commands.bukkit; -import java.util.Set; - import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.util.Msg; - import org.apache.commons.lang.StringUtils; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import java.util.Set; + public class PlaceholderAPICommands implements CommandExecutor { private PlaceholderAPIPlugin plugin; diff --git a/src/main/java/me/clip/placeholderapi/commands/spigot/ExpansionCloudCommands.java b/src/main/java/me/clip/placeholderapi/commands/spigot/ExpansionCloudCommands.java index dcfeb84..766d70c 100644 --- a/src/main/java/me/clip/placeholderapi/commands/spigot/ExpansionCloudCommands.java +++ b/src/main/java/me/clip/placeholderapi/commands/spigot/ExpansionCloudCommands.java @@ -20,9 +20,6 @@ */ package me.clip.placeholderapi.commands.spigot; -import java.util.Map; -import java.util.Map.Entry; - import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.expansion.PlaceholderExpansion; @@ -32,13 +29,15 @@ import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; - import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import java.util.Map; +import java.util.Map.Entry; + public class ExpansionCloudCommands implements CommandExecutor { private PlaceholderAPIPlugin plugin; diff --git a/src/main/java/me/clip/placeholderapi/commands/spigot/PlaceholderAPICommands.java b/src/main/java/me/clip/placeholderapi/commands/spigot/PlaceholderAPICommands.java index af5456c..4f3d9d4 100644 --- a/src/main/java/me/clip/placeholderapi/commands/spigot/PlaceholderAPICommands.java +++ b/src/main/java/me/clip/placeholderapi/commands/spigot/PlaceholderAPICommands.java @@ -20,13 +20,10 @@ */ package me.clip.placeholderapi.commands.spigot; -import java.util.Set; - import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.util.Msg; - import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.command.Command; @@ -34,6 +31,8 @@ import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import java.util.Set; + public class PlaceholderAPICommands implements CommandExecutor { private PlaceholderAPIPlugin plugin; diff --git a/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java b/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java index 768c49b..1e3fcb3 100644 --- a/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java +++ b/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java @@ -22,8 +22,6 @@ package me.clip.placeholderapi.configuration; import me.clip.placeholderapi.PlaceholderAPIPlugin; -import org.bukkit.configuration.file.FileConfiguration; - public class PlaceholderAPIConfig { private PlaceholderAPIPlugin plugin; @@ -33,32 +31,7 @@ public class PlaceholderAPIConfig { } public void loadDefConfig() { - - FileConfiguration c = plugin.getConfig(); - - c.options().header("PlaceholderAPI version "+plugin.getDescription().getVersion()+"" - + "\nCreated by extended_clip" - + "\n" - + "\nNo placeholders are provided with this plugin." - + "\nDownload placeholders with /papi ecloud" - + "\nExample:" - + "\n/papi ecloud refresh" - + "\n/papi ecloud list all" - + "\n/papi ecloud list all 2" - + "\n/papi ecloud download Player" - + "\n/papi ecloud download Vault" - + "\n/papi reload"); - - c.set("auto_install_expansions", null); - c.set("cloud_enable_unverified_expansions", null); - c.addDefault("check_updates", true); - c.addDefault("cloud_enabled", true); - c.addDefault("cloud_allow_unverified_expansions", false); - c.addDefault("boolean.true", "yes"); - c.addDefault("boolean.false", "no"); - c.addDefault("date_format", "MM/dd/yy HH:mm:ss"); - c.options().copyDefaults(true); - plugin.saveConfig(); + plugin.saveDefaultConfig(); plugin.reloadConfig(); } @@ -76,7 +49,6 @@ public class PlaceholderAPIConfig { public void setCloudEnabled(boolean b) { plugin.getConfig().set("cloud_enabled", b); - plugin.saveConfig(); plugin.reloadConfig(); } diff --git a/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java b/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java index 37dddbe..b680b87 100644 --- a/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java +++ b/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java @@ -21,7 +21,6 @@ package me.clip.placeholderapi.events; import me.clip.placeholderapi.PlaceholderHook; - import org.bukkit.event.Event; import org.bukkit.event.HandlerList; diff --git a/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java b/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java index 54821d6..6405588 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java @@ -20,22 +20,21 @@ */ package me.clip.placeholderapi.expansion; +import me.clip.placeholderapi.PlaceholderAPI; +import me.clip.placeholderapi.PlaceholderAPIPlugin; +import me.clip.placeholderapi.PlaceholderHook; +import me.clip.placeholderapi.expansion.cloud.CloudExpansion; +import me.clip.placeholderapi.util.FileUtil; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.event.Listener; + import java.lang.reflect.Constructor; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import me.clip.placeholderapi.PlaceholderAPI; -import me.clip.placeholderapi.PlaceholderAPIPlugin; -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.event.Listener; - -import me.clip.placeholderapi.PlaceholderHook; -import me.clip.placeholderapi.expansion.cloud.CloudExpansion; -import me.clip.placeholderapi.util.FileUtil; - public final class ExpansionManager { private PlaceholderAPIPlugin plugin; @@ -78,38 +77,33 @@ public final class ExpansionManager { if (c instanceof Configurable) { Map defaults = ((Configurable) c).getDefaults(); - String pre = "expansions." + c.getIdentifier() + "."; + FileConfiguration cfg = plugin.getConfig(); - if (defaults != null && !defaults.isEmpty()) { + boolean save = false; - FileConfiguration cfg = plugin.getConfig(); - - boolean save = false; - - 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; - cfg.set(pre + entries.getKey(), null); - } - } else { - if (!cfg.contains(pre + entries.getKey())) { - save = true; - cfg.set(pre + entries.getKey(), entries.getValue()); - } - } + for (Entry entries : defaults.entrySet()) { + if (entries.getKey() == null || entries.getKey().isEmpty()) { + continue; } - if (save) { - plugin.saveConfig(); - plugin.reloadConfig(); + if (entries.getValue() == null) { + if (cfg.contains(pre + entries.getKey())) { + save = true; + cfg.set(pre + entries.getKey(), null); + } + } else { + if (!cfg.contains(pre + entries.getKey())) { + save = true; + cfg.set(pre + entries.getKey(), entries.getValue()); + } } } + + if (save) { + plugin.saveConfig(); + plugin.reloadConfig(); + } } if (c instanceof VersionSpecific) { diff --git a/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java b/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java index bee749a..2132216 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java @@ -20,16 +20,15 @@ */ package me.clip.placeholderapi.expansion; -import java.util.List; - import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderHook; - import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; +import java.util.List; + public abstract class PlaceholderExpansion extends PlaceholderHook { /** 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 6190d5e..0f64de3 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java @@ -20,10 +20,10 @@ */ package me.clip.placeholderapi.expansion.cloud; -import java.util.concurrent.TimeUnit; - import me.clip.placeholderapi.util.TimeUtil; +import java.util.concurrent.TimeUnit; + public class CloudExpansion { 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 850f225..e70ee55 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java @@ -20,22 +20,9 @@ */ package me.clip.placeholderapi.expansion.cloud; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - import me.clip.placeholderapi.PlaceholderAPIPlugin; +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import me.clip.placeholderapi.util.Msg; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; @@ -43,8 +30,11 @@ import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import me.clip.placeholderapi.util.Msg; +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.util.*; public class ExpansionCloudManager { diff --git a/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java b/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java index d4fdbce..95c444a 100644 --- a/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java +++ b/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java @@ -21,11 +21,10 @@ package me.clip.placeholderapi.external; import me.clip.placeholderapi.PlaceholderAPI; +import me.clip.placeholderapi.PlaceholderHook; import org.apache.commons.lang.Validate; import org.bukkit.plugin.Plugin; -import me.clip.placeholderapi.PlaceholderHook; - @Deprecated public abstract class EZPlaceholderHook extends PlaceholderHook { diff --git a/src/main/java/me/clip/placeholderapi/metrics/Metrics.java b/src/main/java/me/clip/placeholderapi/metrics/Metrics.java deleted file mode 100644 index b0e7d74..0000000 --- a/src/main/java/me/clip/placeholderapi/metrics/Metrics.java +++ /dev/null @@ -1,666 +0,0 @@ -package me.clip.placeholderapi.metrics; - -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.plugin.RegisteredServiceProvider; -import org.bukkit.plugin.ServicePriority; -import org.bukkit.plugin.java.JavaPlugin; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; - -import javax.net.ssl.HttpsURLConnection; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Timer; -import java.util.TimerTask; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.logging.Level; -import java.util.zip.GZIPOutputStream; - -/** - * bStats collects some data for plugin authors. - * Check out https://bStats.org/ to learn more about bStats! - */ -public class Metrics { - - static { - // You can use the property to disable the check in your test environment - if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) { - // Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D - final String defaultPackage = new String( - new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'}); - final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'}); - // We want to make sure nobody just copy & pastes the example and use the wrong package names - if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) { - throw new IllegalStateException("bStats Metrics class has not been relocated correctly!"); - } - } - } - - // The version of this bStats class - public static final int B_STATS_VERSION = 1; - - // The url to which the data is sent - private static final String URL = "https://bStats.org/submitData/bukkit"; - - // Should failed requests be logged? - private static boolean logFailedRequests; - - // The uuid of the server - private static String serverUUID; - - // The plugin - private final JavaPlugin plugin; - - // A list with all custom charts - private final List charts = new ArrayList<>(); - - /** - * Class constructor. - * - * @param plugin The plugin which stats should be submitted. - */ - public Metrics(JavaPlugin plugin) { - if (plugin == null) { - throw new IllegalArgumentException("Plugin cannot be null!"); - } - this.plugin = plugin; - - // Get the config file - File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats"); - File configFile = new File(bStatsFolder, "config.yml"); - YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); - - // Check if the config file exists - if (!config.isSet("serverUuid")) { - - // Add default values - config.addDefault("enabled", true); - // Every server gets it's unique random id. - config.addDefault("serverUuid", UUID.randomUUID().toString()); - // Should failed request be logged? - config.addDefault("logFailedRequests", false); - - // Inform the server owners about bStats - config.options().header( - "bStats collects some data for plugin authors like how many servers are using their plugins.\n" + - "To honor their work, you should not disable it.\n" + - "This has nearly no effect on the server performance!\n" + - "Check out https://bStats.org/ to learn more :)" - ).copyDefaults(true); - try { - config.save(configFile); - } catch (IOException ignored) { } - } - - // Load the data - serverUUID = config.getString("serverUuid"); - logFailedRequests = config.getBoolean("logFailedRequests", false); - if (config.getBoolean("enabled", true)) { - boolean found = false; - // Search for all other bStats Metrics classes to see if we are the first one - for (Class service : Bukkit.getServicesManager().getKnownServices()) { - try { - service.getField("B_STATS_VERSION"); // Our identifier :) - found = true; // We aren't the first - break; - } catch (NoSuchFieldException ignored) { } - } - // Register our service - Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal); - if (!found) { - // We are the first! - startSubmitting(); - } - } - } - - /** - * Adds a custom chart. - * - * @param chart The chart to add. - */ - public void addCustomChart(CustomChart chart) { - if (chart == null) { - throw new IllegalArgumentException("Chart cannot be null!"); - } - charts.add(chart); - } - - /** - * Starts the Scheduler which submits our data every 30 minutes. - */ - private void startSubmitting() { - final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags - timer.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - if (!plugin.isEnabled()) { // Plugin was disabled - timer.cancel(); - return; - } - // Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler - // Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;) - Bukkit.getScheduler().runTask(plugin, new Runnable() { - @Override - public void run() { - submitData(); - } - }); - } - }, 1000*60*5, 1000*60*30); - // Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start - // WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted! - // WARNING: Just don't do it! - } - - /** - * Gets the plugin specific data. - * This method is called using Reflection. - * - * @return The plugin specific data. - */ - public JSONObject getPluginData() { - JSONObject data = new JSONObject(); - - String pluginName = plugin.getDescription().getName(); - String pluginVersion = plugin.getDescription().getVersion(); - - data.put("pluginName", pluginName); // Append the name of the plugin - data.put("pluginVersion", pluginVersion); // Append the version of the plugin - JSONArray customCharts = new JSONArray(); - for (CustomChart customChart : charts) { - // Add the data of the custom charts - JSONObject chart = customChart.getRequestJsonObject(); - if (chart == null) { // If the chart is null, we skip it - continue; - } - customCharts.add(chart); - } - data.put("customCharts", customCharts); - - return data; - } - - /** - * Gets the server specific data. - * - * @return The server specific data. - */ - private JSONObject getServerData() { - // Minecraft specific data - int playerAmount; - try { - // Around MC 1.8 the return type was changed to a collection from an array, - // This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection; - Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers"); - playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class) - ? ((Collection) onlinePlayersMethod.invoke(Bukkit.getServer())).size() - : ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length; - } catch (Exception e) { - playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed - } - int onlineMode = Bukkit.getOnlineMode() ? 1 : 0; - String bukkitVersion = org.bukkit.Bukkit.getVersion(); - bukkitVersion = bukkitVersion.substring(bukkitVersion.indexOf("MC: ") + 4, bukkitVersion.length() - 1); - - // OS/Java specific data - String javaVersion = System.getProperty("java.version"); - String osName = System.getProperty("os.name"); - String osArch = System.getProperty("os.arch"); - String osVersion = System.getProperty("os.version"); - int coreCount = Runtime.getRuntime().availableProcessors(); - - JSONObject data = new JSONObject(); - - data.put("serverUUID", serverUUID); - - data.put("playerAmount", playerAmount); - data.put("onlineMode", onlineMode); - data.put("bukkitVersion", bukkitVersion); - - data.put("javaVersion", javaVersion); - data.put("osName", osName); - data.put("osArch", osArch); - data.put("osVersion", osVersion); - data.put("coreCount", coreCount); - - return data; - } - - /** - * Collects the data and sends it afterwards. - */ - private void submitData() { - final JSONObject data = getServerData(); - - JSONArray pluginData = new JSONArray(); - // Search for all other bStats Metrics classes to get their plugin data - for (Class service : Bukkit.getServicesManager().getKnownServices()) { - try { - service.getField("B_STATS_VERSION"); // Our identifier :) - - for (RegisteredServiceProvider provider : Bukkit.getServicesManager().getRegistrations(service)) { - try { - pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider())); - } catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { } - } - } catch (NoSuchFieldException ignored) { } - } - - data.put("plugins", pluginData); - - // Create a new thread for the connection to the bStats server - new Thread(new Runnable() { - @Override - public void run() { - try { - // Send the data - sendData(data); - } catch (Exception e) { - // Something went wrong! :( - if (logFailedRequests) { - plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e); - } - } - } - }).start(); - } - - /** - * Sends the data to the bStats server. - * - * @param data The data to send. - * @throws Exception If the request failed. - */ - private static void sendData(JSONObject data) throws Exception { - if (data == null) { - throw new IllegalArgumentException("Data cannot be null!"); - } - if (Bukkit.isPrimaryThread()) { - throw new IllegalAccessException("This method must not be called from the main thread!"); - } - HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection(); - - // Compress the data to save bandwidth - byte[] compressedData = compress(data.toString()); - - // Add headers - connection.setRequestMethod("POST"); - connection.addRequestProperty("Accept", "application/json"); - connection.addRequestProperty("Connection", "close"); - connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request - connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length)); - connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format - connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION); - - // Send data - connection.setDoOutput(true); - DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream()); - outputStream.write(compressedData); - outputStream.flush(); - outputStream.close(); - - connection.getInputStream().close(); // We don't care about the response - Just send our data :) - } - - /** - * Gzips the given String. - * - * @param str The string to gzip. - * @return The gzipped String. - * @throws IOException If the compression failed. - */ - private static byte[] compress(final String str) throws IOException { - if (str == null) { - return null; - } - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - GZIPOutputStream gzip = new GZIPOutputStream(outputStream); - gzip.write(str.getBytes("UTF-8")); - gzip.close(); - return outputStream.toByteArray(); - } - - /** - * Represents a custom chart. - */ - public static abstract class CustomChart { - - // The id of the chart - final String chartId; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - */ - CustomChart(String chartId) { - if (chartId == null || chartId.isEmpty()) { - throw new IllegalArgumentException("ChartId cannot be null or empty!"); - } - this.chartId = chartId; - } - - private JSONObject getRequestJsonObject() { - JSONObject chart = new JSONObject(); - chart.put("chartId", chartId); - try { - JSONObject data = getChartData(); - if (data == null) { - // If the data is null we don't send the chart. - return null; - } - chart.put("data", data); - } catch (Throwable t) { - if (logFailedRequests) { - Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t); - } - return null; - } - return chart; - } - - protected abstract JSONObject getChartData() throws Exception; - - } - - /** - * Represents a custom simple pie. - */ - public static class SimplePie extends CustomChart { - - private final Callable callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SimplePie(String chartId, Callable callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - String value = callable.call(); - if (value == null || value.isEmpty()) { - // Null = skip the chart - return null; - } - data.put("value", value); - return data; - } - } - - /** - * Represents a custom advanced pie. - */ - public static class AdvancedPie extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public AdvancedPie(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - continue; // Skip this invalid - } - allSkipped = false; - values.put(entry.getKey(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - data.put("values", values); - return data; - } - } - - /** - * Represents a custom drilldown pie. - */ - public static class DrilldownPie extends CustomChart { - - private final Callable>> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public DrilldownPie(String chartId, Callable>> callable) { - super(chartId); - this.callable = callable; - } - - @Override - public JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map> map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean reallyAllSkipped = true; - for (Map.Entry> entryValues : map.entrySet()) { - JSONObject value = new JSONObject(); - boolean allSkipped = true; - for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { - value.put(valueEntry.getKey(), valueEntry.getValue()); - allSkipped = false; - } - if (!allSkipped) { - reallyAllSkipped = false; - values.put(entryValues.getKey(), value); - } - } - if (reallyAllSkipped) { - // Null = skip the chart - return null; - } - data.put("values", values); - return data; - } - } - - /** - * Represents a custom single line chart. - */ - public static class SingleLineChart extends CustomChart { - - private final Callable callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SingleLineChart(String chartId, Callable callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - int value = callable.call(); - if (value == 0) { - // Null = skip the chart - return null; - } - data.put("value", value); - return data; - } - - } - - /** - * Represents a custom multi line chart. - */ - public static class MultiLineChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public MultiLineChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - continue; // Skip this invalid - } - allSkipped = false; - values.put(entry.getKey(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - data.put("values", values); - return data; - } - - } - - /** - * Represents a custom simple bar chart. - */ - public static class SimpleBarChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SimpleBarChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - for (Map.Entry entry : map.entrySet()) { - JSONArray categoryValues = new JSONArray(); - categoryValues.add(entry.getValue()); - values.put(entry.getKey(), categoryValues); - } - data.put("values", values); - return data; - } - - } - - /** - * Represents a custom advanced bar chart. - */ - public static class AdvancedBarChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public AdvancedBarChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JSONObject getChartData() throws Exception { - JSONObject data = new JSONObject(); - JSONObject values = new JSONObject(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue().length == 0) { - continue; // Skip this invalid - } - allSkipped = false; - JSONArray categoryValues = new JSONArray(); - for (int categoryValue : entry.getValue()) { - categoryValues.add(categoryValue); - } - values.put(entry.getKey(), categoryValues); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - data.put("values", values); - return data; - } - - } -} \ No newline at end of file diff --git a/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java b/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java index ade6e77..7cabfc6 100644 --- a/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java +++ b/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java @@ -1,12 +1,5 @@ package me.clip.placeholderapi.updatechecker; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.regex.Pattern; - -import javax.net.ssl.HttpsURLConnection; - import me.clip.placeholderapi.PlaceholderAPIPlugin; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -15,6 +8,12 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; +import javax.net.ssl.HttpsURLConnection; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.regex.Pattern; + /** * thanks maxim */ diff --git a/src/main/java/me/clip/placeholderapi/util/FileUtil.java b/src/main/java/me/clip/placeholderapi/util/FileUtil.java index 169d32f..417cb31 100644 --- a/src/main/java/me/clip/placeholderapi/util/FileUtil.java +++ b/src/main/java/me/clip/placeholderapi/util/FileUtil.java @@ -20,6 +20,8 @@ */ package me.clip.placeholderapi.util; +import me.clip.placeholderapi.PlaceholderAPIPlugin; + import java.io.File; import java.io.FilenameFilter; import java.net.URL; @@ -29,8 +31,6 @@ import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; -import me.clip.placeholderapi.PlaceholderAPIPlugin; - public class FileUtil { public static List> getClasses(String folder, Class type) { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..d52ac66 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,18 @@ +# PlaceholderAPI version ${project.version} +# Created by extended_clip +# No placeholders are provided with this plugin. +# Download placeholders with /papi ecloud +# Example: +# /papi ecloud refresh +# /papi ecloud list all +# /papi ecloud list all 2 +# /papi ecloud download Player +# /papi ecloud download Vault +# /papi reload +check_updates: true +cloud_enabled: true +cloud_allow_unverified_expansions: false +boolean: + 'true': 'yes' + 'false': 'no' +date_format: MM/dd/yy HH:mm:ss diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 16e4edf..addce9c 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,8 +1,8 @@ -name: PlaceholderAPI +name: ${project.name} main: me.clip.placeholderapi.PlaceholderAPIPlugin -version: ${pom.version} +version: ${project.version} author: [extended_clip] -description: A placeholder provider +description: ${project.description} permissions: placeholderapi.*: description: ability to use all commands