From c622b2b102f1099857a0e5a98ecd6e094aedb910 Mon Sep 17 00:00:00 2001 From: Esophose Date: Thu, 15 Jul 2021 03:41:52 -0600 Subject: [PATCH] Minor cleanup, remove legacy metrics --- build.gradle | 5 +- .../playerparticles/PlayerParticles.java | 9 +- .../manager/ParticleManager.java | 4 +- .../particles/ParticleEffect.java | 1 + .../particles/spawning/ParticleSpawner.java | 5 +- .../playerparticles/util/LegacyMetrics.java | 347 ------------------ 6 files changed, 10 insertions(+), 361 deletions(-) delete mode 100644 src/main/java/dev/esophose/playerparticles/util/LegacyMetrics.java diff --git a/build.gradle b/build.gradle index 96c5063..d85a4fa 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ sourceCompatibility = 1.8 targetCompatibility = 1.8 compileJava.options.encoding = 'UTF-8' group = 'dev.esophose' -version = '7.20' +version = '7.21' java { withJavadocJar() @@ -32,11 +32,10 @@ dependencies { api 'com.zaxxer:HikariCP:3.2.0' api 'org.bstats:bstats-bukkit-lite:1.7' api 'org.codemc.worldguardwrapper:worldguardwrapper:1.2.0-SNAPSHOT' - compileOnly 'com.googlecode.json-simple:json-simple:1.1.1' compileOnly 'org.jetbrains:annotations:16.0.2' compileOnly 'me.clip:placeholderapi:2.10.4' compileOnly 'org.xerial:sqlite-jdbc:3.23.1' - compileOnly 'org.spigotmc:spigot:1.17' + compileOnly 'org.spigotmc:spigot:1.17.1' } shadowJar { diff --git a/src/main/java/dev/esophose/playerparticles/PlayerParticles.java b/src/main/java/dev/esophose/playerparticles/PlayerParticles.java index 4bcd037..064de64 100644 --- a/src/main/java/dev/esophose/playerparticles/PlayerParticles.java +++ b/src/main/java/dev/esophose/playerparticles/PlayerParticles.java @@ -24,7 +24,6 @@ import dev.esophose.playerparticles.manager.PermissionManager; import dev.esophose.playerparticles.manager.PluginUpdateManager; import dev.esophose.playerparticles.particles.listener.PPlayerCombatListener; import dev.esophose.playerparticles.particles.listener.PPlayerMovementListener; -import dev.esophose.playerparticles.util.LegacyMetrics; import dev.esophose.playerparticles.util.NMSUtil; import java.util.LinkedHashMap; import java.util.Map; @@ -71,13 +70,9 @@ public class PlayerParticles extends JavaPlugin { pm.registerEvents(new PPlayerCombatListener(), this); pm.registerEvents(new PlayerChatHook(), this); - if (Setting.SEND_METRICS.getBoolean()) { - if (NMSUtil.getVersionNumber() > 7) { + if (Setting.SEND_METRICS.getBoolean()) + if (NMSUtil.getVersionNumber() > 7) new MetricsLite(this, 3531); - } else { - new LegacyMetrics(this); - } - } if (PlaceholderAPIHook.enabled()) new ParticlePlaceholderExpansion(this).register(); diff --git a/src/main/java/dev/esophose/playerparticles/manager/ParticleManager.java b/src/main/java/dev/esophose/playerparticles/manager/ParticleManager.java index 89a2248..8e16999 100644 --- a/src/main/java/dev/esophose/playerparticles/manager/ParticleManager.java +++ b/src/main/java/dev/esophose/playerparticles/manager/ParticleManager.java @@ -260,9 +260,9 @@ public class ParticleManager extends Manager implements Listener, Runnable { } } - for (PParticle pparticle : getParticlesWithPlayer(particle, location, pplayer.getPlayer())) + for (PParticle pparticle : this.getParticlesWithPlayer(particle, location, pplayer.getPlayer())) ParticleEffect.display(particle, pparticle, particle.getStyle().hasLongRangeVisibility(), pplayer.getPlayer()); - } + } } /** diff --git a/src/main/java/dev/esophose/playerparticles/particles/ParticleEffect.java b/src/main/java/dev/esophose/playerparticles/particles/ParticleEffect.java index af48109..8627b4c 100644 --- a/src/main/java/dev/esophose/playerparticles/particles/ParticleEffect.java +++ b/src/main/java/dev/esophose/playerparticles/particles/ParticleEffect.java @@ -452,6 +452,7 @@ public enum ParticleEffect { * @param center Center location of the effect * @param isLongRange If the particle can be viewed from long range * @param owner The player that owns the particles + * @param size The size of the particles * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect */ public void display(ColorTransition colorTransition, double offsetX, double offsetY, double offsetZ, int amount, Location center, boolean isLongRange, Player owner, float size) { diff --git a/src/main/java/dev/esophose/playerparticles/particles/spawning/ParticleSpawner.java b/src/main/java/dev/esophose/playerparticles/particles/spawning/ParticleSpawner.java index e7992ec..1788565 100644 --- a/src/main/java/dev/esophose/playerparticles/particles/spawning/ParticleSpawner.java +++ b/src/main/java/dev/esophose/playerparticles/particles/spawning/ParticleSpawner.java @@ -79,6 +79,7 @@ public abstract class ParticleSpawner { * @param center Center location of the effect * @param isLongRange If the particle can be viewed from long range * @param owner The player that owns the particles + * @param size The size of the particles * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect */ public abstract void display(ParticleEffect particleEffect, ColorTransition colorTransition, double offsetX, double offsetY, double offsetZ, int amount, Location center, boolean isLongRange, Player owner, float size); @@ -137,9 +138,9 @@ public abstract class ParticleSpawner { if (player == null || target == null) return true; - /*for (MetadataValue meta : target.getMetadata("vanished")) + for (MetadataValue meta : target.getMetadata("vanished")) if (meta.asBoolean()) - return false;*/ + return false; return player.canSee(target); } diff --git a/src/main/java/dev/esophose/playerparticles/util/LegacyMetrics.java b/src/main/java/dev/esophose/playerparticles/util/LegacyMetrics.java deleted file mode 100644 index de8b83f..0000000 --- a/src/main/java/dev/esophose/playerparticles/util/LegacyMetrics.java +++ /dev/null @@ -1,347 +0,0 @@ -package dev.esophose.playerparticles.util; - -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.Timer; -import java.util.TimerTask; -import java.util.UUID; -import java.util.logging.Level; -import java.util.zip.GZIPOutputStream; -import javax.net.ssl.HttpsURLConnection; -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.RegisteredServiceProvider; -import org.bukkit.plugin.ServicePriority; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; - -/** - * bStats collects some data for plugin authors. - *

- * Check out https://bStats.org/ to learn more about bStats! - */ -@SuppressWarnings({"WeakerAccess", "unused"}) -public class LegacyMetrics { - - 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 (LegacyMetrics.class.getPackage().getName().equals(defaultPackage) || LegacyMetrics.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"; - - // Is bStats enabled on this server? - private boolean enabled; - - // Should failed requests be logged? - private static boolean logFailedRequests; - - // Should the sent data be logged? - private static boolean logSentData; - - // Should the response text be logged? - private static boolean logResponseStatusText; - - // The uuid of the server - private static String serverUUID; - - // The plugin - private final Plugin plugin; - - /** - * Class constructor. - * - * @param plugin The plugin which stats should be submitted. - */ - public LegacyMetrics(Plugin 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); - // Should the sent data be logged? - config.addDefault("logSentData", false); - // Should the response text be logged? - config.addDefault("logResponseStatusText", 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); - enabled = config.getBoolean("enabled", true); - if (enabled) { - 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(LegacyMetrics.class, this, plugin, ServicePriority.Normal); - if (!found) { - // We are the first! - startSubmitting(); - } - } - } - - /** - * Checks if bStats is enabled. - * - * @return Whether bStats is enabled or not. - */ - public boolean isEnabled() { - return enabled; - } - - /** - * 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, () -> 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(); - 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 = Bukkit.getVersion(); - - // 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(plugin, 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 plugin Any plugin. It's just used to get a logger instance. - * @param data The data to send. - * @throws Exception If the request failed. - */ - private static void sendData(Plugin plugin, 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!"); - } - if (logSentData) { - plugin.getLogger().info("Sending data to bStats: " + data.toString()); - } - 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(); - - InputStream inputStream = connection.getInputStream(); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - - StringBuilder builder = new StringBuilder(); - String line; - while ((line = bufferedReader.readLine()) != null) { - builder.append(line); - } - bufferedReader.close(); - if (logResponseStatusText) { - plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString()); - } - } - - /** - * 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(StandardCharsets.UTF_8)); - gzip.close(); - return outputStream.toByteArray(); - } - -} \ No newline at end of file