aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/MylesAndMore/tumble/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/MylesAndMore/tumble/api')
-rw-r--r--src/main/java/com/MylesAndMore/tumble/api/Generator.java120
-rw-r--r--src/main/java/com/MylesAndMore/tumble/api/Layers.java373
-rw-r--r--src/main/java/com/MylesAndMore/tumble/api/Metrics.java865
3 files changed, 0 insertions, 1358 deletions
diff --git a/src/main/java/com/MylesAndMore/tumble/api/Generator.java b/src/main/java/com/MylesAndMore/tumble/api/Generator.java
deleted file mode 100644
index db8bacc..0000000
--- a/src/main/java/com/MylesAndMore/tumble/api/Generator.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package com.MylesAndMore.tumble.api;
-
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.World;
-import org.bukkit.block.Block;
-import org.bukkit.block.BlockFace;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
-
-/**
- * This class holds the methods that generate blocks in-game such as cylinders, cubiods, and clump logic.
- */
-public class Generator {
- /**
- * Generates a layer (bascally just a cylinder) as best as it can w/ blocks
- *
- * @return A list of Blocks containing all the blocks it just changed
- *
- * @param center The center of the layer (Location)
- * @param radius The whole number radius of the circle
- * @param height The whole number height of the circle (1 for a flat layer)
- * @param material The Material to use for generation
- */
- public static List<Block> generateLayer(Location center, int radius, int height, Material material) {
- int Cx = center.getBlockX();
- int Cy = center.getBlockY();
- int Cz = center.getBlockZ();
- World world = center.getWorld();
- List<Block> blocks = new ArrayList<>();
-
- int rSq = radius * radius;
-
- for (int y = Cy; y < Cy + height; y++) {
- for (int x = Cx - radius; x <= Cx + radius; x++) {
- for (int z = Cz - radius; z <= Cz + radius; z++) {
- if ((Cx - x) * (Cx - x) + (Cz - z) * (Cz - z) <= rSq) {
- world.getBlockAt(x, y, z).setType(material);
- blocks.add(world.getBlockAt(x, y, z));
- }
- }
- }
- }
- return blocks;
- }
-
- /**
- * Generates a cubiod (literally just a ripoff fill command)
- * @param firstPos The first Location to fill (first three coords in a fill command)
- * @param secondPos The second Location to fill to (second three coords)
- * @param material The Material to fill
- */
- public static List<Block> generateCuboid(Location firstPos, Location secondPos, Material material) {
- World world = firstPos.getWorld();
- List<Block> blocks = new ArrayList<>();
- int fX = firstPos.getBlockX();
- int fY = firstPos.getBlockY();
- int fZ = firstPos.getBlockZ();
- int sX = secondPos.getBlockX();
- int sY = secondPos.getBlockY();
- int sZ = secondPos.getBlockZ();
-
- for (int x = fX; x <= sX; x++) {
- for (int y = fY; y <= sY; y++) {
- for (int z = fZ; z <= sZ; z++) {
- world.getBlockAt(x, y, z).setType(material);
- blocks.add(world.getBlockAt(x, y, z));
- }
- }
- }
- return blocks;
- }
-
- /**
- * Generates clumps in a pre-generated layer.
- * @param blockList A list of block Locations that this method is allowed to edit
- * @param materialList A list of Materials for the generator to randomly choose from.
- * Keep in mind that not all Materials may be used, the amount used depends on the size of the layer.
- * More Materials = more randomization
- */
- public static void generateClumps(List<Block> blockList, List<Material> materialList) {
- // Define random class
- Random random = new Random();
- // Define new blocks list so we can manipulate it
- List<Block> blocks = new ArrayList<>(blockList);
- // Define new shuffled Materials list
- List<Material> materials = new ArrayList<>(materialList);
- Collections.shuffle(materials);
- // This loop will run until there are no blocks left to change
- while (blocks.size() > 0) {
- // Get a random Material from the provided materials list
- Material randomMaterial = materials.get(random.nextInt(materials.size()));
- // Gets the first Block from the list, to modify
- Block aBlock = blocks.get(0);
- // Modifies the block
- aBlock.setType(randomMaterial);
- // Get the blocks around that and change it to that same material
- if (blocks.contains(aBlock.getRelative(BlockFace.NORTH))) {
- aBlock.getRelative(BlockFace.NORTH).setType(randomMaterial);
- blocks.remove(aBlock.getRelative(BlockFace.NORTH));
- }
- if (blocks.contains(aBlock.getRelative(BlockFace.SOUTH))) {
- aBlock.getRelative(BlockFace.SOUTH).setType(randomMaterial);
- blocks.remove(aBlock.getRelative(BlockFace.SOUTH));
- }
- if (blocks.contains(aBlock.getRelative(BlockFace.EAST))) {
- aBlock.getRelative(BlockFace.EAST).setType(randomMaterial);
- blocks.remove(aBlock.getRelative(BlockFace.EAST));
- }
- if (blocks.contains(aBlock.getRelative(BlockFace.WEST))) {
- aBlock.getRelative(BlockFace.WEST).setType(randomMaterial);
- blocks.remove(aBlock.getRelative(BlockFace.WEST));
- }
- blocks.remove(aBlock);
- }
- }
-}
diff --git a/src/main/java/com/MylesAndMore/tumble/api/Layers.java b/src/main/java/com/MylesAndMore/tumble/api/Layers.java
deleted file mode 100644
index d0d5890..0000000
--- a/src/main/java/com/MylesAndMore/tumble/api/Layers.java
+++ /dev/null
@@ -1,373 +0,0 @@
-package com.MylesAndMore.tumble.api;
-
-import org.bukkit.Material;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-/**
- * This class is dedicated to storing the different types of layers that can be generated.
- */
-public class Layers {
-
- public Layers(){
- matList.add(gen0);
- matList.add(gen1);
- matList.add(gen2);
- matList.add(gen3);
- matList.add(gen4);
- matList.add(gen5);
- matList.add(gen6);
- matList.add(gen7);
- matList.add(gen8);
- matList.add(gen9);
- matList.add(gen10);
- matList.add(gen12);
- matList.add(gen14);
- matList.add(gen15);
- matList.add(gen16);
- matList.add(gen0);
- matList.add(gen1);
- matList.add(gen2);
- matList.add(gen3);
- matList.add(gen4);
- matList.add(gen5);
- matList.add(gen6);
- matList.add(gen7);
- matList.add(gen8);
- matList.add(gen9);
- matList.add(gen10);
- matList.add(gen12);
- matList.add(gen14);
- matList.add(gen15);
- matList.add(gen16);
- matList.add(gen0);
- matList.add(gen1);
- matList.add(gen2);
- matList.add(gen3);
- matList.add(gen4);
- matList.add(gen5);
- matList.add(gen6);
- matList.add(gen7);
- matList.add(gen8);
- matList.add(gen9);
- matList.add(gen10);
- matList.add(gen12);
- matList.add(gen14);
- matList.add(gen15);
- matList.add(gen16);
- // Troll glass layer
- matList.add(gen11);
-
- safeMatList.add(gen1);
- safeMatList.add(gen2);
- safeMatList.add(gen4);
- safeMatList.add(gen5);
- safeMatList.add(gen7);
- safeMatList.add(gen9);
- safeMatList.add(gen10);
- safeMatList.add(gen1);
- safeMatList.add(gen2);
- safeMatList.add(gen4);
- safeMatList.add(gen5);
- safeMatList.add(gen7);
- safeMatList.add(gen9);
- safeMatList.add(gen10);
- safeMatList.add(gen1);
- safeMatList.add(gen2);
- safeMatList.add(gen4);
- safeMatList.add(gen5);
- safeMatList.add(gen7);
- safeMatList.add(gen9);
- safeMatList.add(gen10);
- // Troll glass layer
- safeMatList.add(gen11);
- }
-
- // Define Random class
- Random random = new Random();
- /**
- * @return A random predefined List of Materials that are okay to use in the clump generator
- */
- public List<Material> getMaterialList() {
- return matList.get(random.nextInt(matList.size()));
- }
-
- /**
- * @return A random predefined List of Materials that are okay to spawn players on top of
- */
- public List<Material> getSafeMaterialList() { return safeMatList.get(random.nextInt(safeMatList.size())); }
-
- // Begin lists
-
- // private final List<Material> gen = new ArrayList<>() {{
- // add(Material.
- // }};
-
- private final List<Material> gen0 = new ArrayList<>() {{
- add(Material.COAL_ORE);
- add(Material.COAL_ORE);
- add(Material.COAL_ORE);
- add(Material.COAL_ORE);
- add(Material.COAL_ORE);
- add(Material.IRON_ORE);
- add(Material.REDSTONE_ORE);
- add(Material.EMERALD_ORE);
- add(Material.GOLD_ORE);
- add(Material.LAPIS_ORE);
- add(Material.DIAMOND_ORE);
- add(Material.GRASS_BLOCK);
- add(Material.GRASS_BLOCK);
- add(Material.GRASS_BLOCK);
- add(Material.GRASS_BLOCK);
- add(Material.COBWEB);
- }};
-
- private final List<Material> gen1 = new ArrayList<>() {{
- add(Material.YELLOW_GLAZED_TERRACOTTA);
- add(Material.LIGHT_BLUE_GLAZED_TERRACOTTA);
- add(Material.GRAY_GLAZED_TERRACOTTA);
- add(Material.PODZOL);
- add(Material.PODZOL);
- add(Material.PODZOL);
- add(Material.ORANGE_GLAZED_TERRACOTTA);
- }};
-
- private final List<Material> gen2 = new ArrayList<>() {{
- add(Material.PINK_TERRACOTTA);
- add(Material.PURPLE_TERRACOTTA);
- add(Material.GRAY_TERRACOTTA);
- add(Material.BLUE_TERRACOTTA);
- add(Material.LIGHT_BLUE_TERRACOTTA);
- add(Material.WHITE_TERRACOTTA);
- add(Material.BROWN_TERRACOTTA);
- add(Material.GREEN_TERRACOTTA);
- add(Material.YELLOW_TERRACOTTA);
- add(Material.PINK_TERRACOTTA);
- add(Material.PURPLE_TERRACOTTA);
- add(Material.GRAY_TERRACOTTA);
- add(Material.BLUE_TERRACOTTA);
- add(Material.LIGHT_BLUE_TERRACOTTA);
- add(Material.WHITE_TERRACOTTA);
- add(Material.BROWN_TERRACOTTA);
- add(Material.GREEN_TERRACOTTA);
- add(Material.YELLOW_TERRACOTTA);
- add(Material.WHITE_STAINED_GLASS);
- add(Material.HONEYCOMB_BLOCK);
- add(Material.HONEYCOMB_BLOCK);
- }};
-
- private final List<Material> gen3 = new ArrayList<>() {{
- add(Material.PACKED_ICE);
- add(Material.PACKED_ICE);
- add(Material.NOTE_BLOCK);
- add(Material.TNT);
- add(Material.LIGHT_BLUE_CONCRETE);
- add(Material.GLASS);
- add(Material.PACKED_ICE);
- add(Material.PACKED_ICE);
- add(Material.NOTE_BLOCK);
- add(Material.TNT);
- add(Material.LIGHT_BLUE_CONCRETE);
- add(Material.GLASS);
- add(Material.SOUL_SAND);
- }};
-
- private final List<Material> gen4 = new ArrayList<>() {{
- add(Material.DIAMOND_BLOCK);
- add(Material.GOLD_BLOCK);
- add(Material.REDSTONE_BLOCK);
- add(Material.REDSTONE_BLOCK);
- add(Material.LAPIS_BLOCK);
- add(Material.LAPIS_BLOCK);
- add(Material.IRON_BLOCK);
- add(Material.COAL_BLOCK);
- add(Material.IRON_BLOCK);
- add(Material.COAL_BLOCK);
- add(Material.IRON_BLOCK);
- add(Material.COAL_BLOCK);
- add(Material.COAL_BLOCK);
- }};
-
- private final List<Material> gen5 = new ArrayList<>() {{
- add(Material.WHITE_TERRACOTTA);
- add(Material.BLUE_ICE);
- add(Material.SOUL_SAND);
- add(Material.STONE_SLAB);
- add(Material.WHITE_TERRACOTTA);
- add(Material.BLUE_ICE);
- add(Material.SOUL_SAND);
- add(Material.STONE_SLAB);
- add(Material.WHITE_TERRACOTTA);
- add(Material.BLUE_ICE);
- add(Material.SOUL_SAND);
- add(Material.STONE_SLAB);
- add(Material.GLOWSTONE);
- add(Material.GLOWSTONE);
- add(Material.HONEY_BLOCK);
- add(Material.SLIME_BLOCK);
- }};
-
- private final List<Material> gen6 = new ArrayList<>() {{
- add(Material.NETHERRACK);
- add(Material.NETHERRACK);
- add(Material.NETHERRACK);
- add(Material.NETHER_BRICKS);
- add(Material.NETHER_BRICKS);
- add(Material.NETHERRACK);
- add(Material.NETHERRACK);
- add(Material.NETHERRACK);
- add(Material.NETHER_BRICKS);
- add(Material.NETHER_BRICKS);
- add(Material.NETHER_GOLD_ORE);
- add(Material.NETHER_GOLD_ORE);
- add(Material.CRIMSON_NYLIUM);
- add(Material.WARPED_NYLIUM);
- add(Material.SOUL_SOIL);
- add(Material.CRACKED_NETHER_BRICKS);
- add(Material.RED_NETHER_BRICKS);
- add(Material.NETHER_WART_BLOCK);
- add(Material.CRYING_OBSIDIAN);
- add(Material.MAGMA_BLOCK);
- }};
-
- private final List<Material> gen7 = new ArrayList<>() {{
- add(Material.END_STONE);
- add(Material.END_STONE_BRICKS);
- add(Material.END_STONE);
- add(Material.END_STONE_BRICKS);
- add(Material.END_STONE);
- add(Material.END_STONE_BRICKS);
- add(Material.END_STONE);
- add(Material.END_STONE_BRICKS);
- add(Material.OBSIDIAN);
- add(Material.PURPUR_BLOCK);
- add(Material.PURPUR_PILLAR);
- add(Material.COBBLESTONE);
- }};
-
- private final List<Material> gen8 = new ArrayList<>() {{
- add(Material.REDSTONE_BLOCK);
- add(Material.REDSTONE_BLOCK);
- add(Material.REDSTONE_LAMP);
- add(Material.TARGET);
- add(Material.DAYLIGHT_DETECTOR);
- add(Material.PISTON);
- add(Material.STICKY_PISTON);
- add(Material.SLIME_BLOCK);
- add(Material.OBSERVER);
- add(Material.HOPPER);
- }};
-
- private final List<Material> gen9 = new ArrayList<>() {{
- add(Material.PRISMARINE);
- add(Material.DARK_PRISMARINE);
- add(Material.BLUE_STAINED_GLASS);
- add(Material.WET_SPONGE);
- add(Material.PRISMARINE_BRICKS);
- add(Material.PRISMARINE_BRICK_SLAB);
- add(Material.DARK_PRISMARINE);
- add(Material.SEA_LANTERN);
- add(Material.TUBE_CORAL_BLOCK);
- add(Material.BRAIN_CORAL_BLOCK);
- add(Material.BUBBLE_CORAL_BLOCK);
- }};
-
- private final List<Material> gen10 = new ArrayList<>() {{
- add(Material.OAK_LOG);
- add(Material.SPRUCE_LOG);
- add(Material.ACACIA_LOG);
- add(Material.STRIPPED_OAK_LOG);
- add(Material.STRIPPED_SPRUCE_LOG);
- add(Material.STRIPPED_ACACIA_LOG);
- add(Material.OAK_WOOD);
- add(Material.SPRUCE_WOOD);
- add(Material.ACACIA_WOOD);
- add(Material.OAK_LEAVES);
- add(Material.SPRUCE_LEAVES);
- add(Material.ACACIA_LEAVES);
- add(Material.OAK_LEAVES);
- add(Material.SPRUCE_LEAVES);
- add(Material.ACACIA_LEAVES);
- }};
-
- private final List<Material> gen11 = new ArrayList<>() {{
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.GLASS);
- add(Material.WHITE_STAINED_GLASS);
- }};
-
- private final List<Material> gen12 = new ArrayList<>() {{
- add(Material.DIRT);
- add(Material.DIRT_PATH);
- add(Material.GRASS_BLOCK);
- add(Material.OAK_SLAB);
- add(Material.BRICK_WALL);
- add(Material.BRICK_STAIRS);
- }};
-
- private final List<Material> gen14 = new ArrayList<>() {{
- add(Material.LECTERN);
- add(Material.OBSIDIAN);
- add(Material.SPONGE);
- add(Material.BEEHIVE);
- add(Material.DRIED_KELP_BLOCK);
- }};
-
- private final List<Material> gen15 = new ArrayList<>() {{
- add(Material.SANDSTONE);
- add(Material.SANDSTONE_SLAB);
- add(Material.RED_SANDSTONE);
- add(Material.RED_SANDSTONE_SLAB);
- add(Material.RED_TERRACOTTA);
- add(Material.TERRACOTTA);
- add(Material.YELLOW_TERRACOTTA);
- }};
-
- private final List<Material> gen16 = new ArrayList<>() {{
- add(Material.JUNGLE_LOG);
- add(Material.STRIPPED_JUNGLE_LOG);
- add(Material.JUNGLE_WOOD);
- add(Material.STRIPPED_JUNGLE_WOOD);
- add(Material.MOSSY_COBBLESTONE);
- add(Material.MOSSY_COBBLESTONE);
- add(Material.MOSSY_COBBLESTONE);
- add(Material.JUNGLE_LEAVES);
- add(Material.JUNGLE_SLAB);
- add(Material.JUNGLE_TRAPDOOR);
- }};
-
- private final List<List<Material>> matList = new ArrayList<>();
-
- private final List<List<Material>> safeMatList = new ArrayList<>();
-
-}
diff --git a/src/main/java/com/MylesAndMore/tumble/api/Metrics.java b/src/main/java/com/MylesAndMore/tumble/api/Metrics.java
deleted file mode 100644
index 411a918..0000000
--- a/src/main/java/com/MylesAndMore/tumble/api/Metrics.java
+++ /dev/null
@@ -1,865 +0,0 @@
-// Do NOT remove this file! The build will fail--it is to enable bStats.
-
-/*
- * This Metrics class was auto-generated and can be copied into your project if you are
- * not using a build tool like Gradle or Maven for dependency management.
- *
- * IMPORTANT: You are not allowed to modify this class, except changing the package.
- *
- * Unallowed modifications include but are not limited to:
- * - Remove the option for users to opt-out
- * - Change the frequency for data submission
- * - Obfuscate the code (every obfucator should allow you to make an exception for specific files)
- * - Reformat the code (if you use a linter, add an exception)
- *
- * Violations will result in a ban of your plugin and account from bStats.
- */
-package com.MylesAndMore.tumble.api;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-import java.util.logging.Level;
-import java.util.stream.Collectors;
-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.java.JavaPlugin;
-
-public class Metrics {
-
- private final Plugin plugin;
-
- private final MetricsBase metricsBase;
-
- /**
- * Creates a new Metrics instance.
- *
- * @param plugin Your plugin instance.
- * @param serviceId The id of the service. It can be found at <a
- * href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
- */
- public Metrics(JavaPlugin plugin, int serviceId) {
- 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);
- if (!config.isSet("serverUuid")) {
- config.addDefault("enabled", true);
- config.addDefault("serverUuid", UUID.randomUUID().toString());
- config.addDefault("logFailedRequests", false);
- config.addDefault("logSentData", false);
- config.addDefault("logResponseStatusText", false);
- // Inform the server owners about bStats
- config
- .options()
- .header(
- "bStats (https://bStats.org) collects some basic information for plugin authors, like how\n"
- + "many people use their plugin and their total player count. It's recommended to keep bStats\n"
- + "enabled, but if you're not comfortable with this, you can turn this setting off. There is no\n"
- + "performance penalty associated with having metrics enabled, and data sent to bStats is fully\n"
- + "anonymous.")
- .copyDefaults(true);
- try {
- config.save(configFile);
- } catch (IOException ignored) {
- }
- }
- // Load the data
- boolean enabled = config.getBoolean("enabled", true);
- String serverUUID = config.getString("serverUuid");
- boolean logErrors = config.getBoolean("logFailedRequests", false);
- boolean logSentData = config.getBoolean("logSentData", false);
- boolean logResponseStatusText = config.getBoolean("logResponseStatusText", false);
- metricsBase =
- new MetricsBase(
- "bukkit",
- serverUUID,
- serviceId,
- enabled,
- this::appendPlatformData,
- this::appendServiceData,
- submitDataTask -> Bukkit.getScheduler().runTask(plugin, submitDataTask),
- plugin::isEnabled,
- (message, error) -> this.plugin.getLogger().log(Level.WARNING, message, error),
- (message) -> this.plugin.getLogger().log(Level.INFO, message),
- logErrors,
- logSentData,
- logResponseStatusText);
- }
-
- /**
- * Adds a custom chart.
- *
- * @param chart The chart to add.
- */
- public void addCustomChart(CustomChart chart) {
- metricsBase.addCustomChart(chart);
- }
-
- private void appendPlatformData(JsonObjectBuilder builder) {
- builder.appendField("playerAmount", getPlayerAmount());
- builder.appendField("onlineMode", Bukkit.getOnlineMode() ? 1 : 0);
- builder.appendField("bukkitVersion", Bukkit.getVersion());
- builder.appendField("bukkitName", Bukkit.getName());
- builder.appendField("javaVersion", System.getProperty("java.version"));
- builder.appendField("osName", System.getProperty("os.name"));
- builder.appendField("osArch", System.getProperty("os.arch"));
- builder.appendField("osVersion", System.getProperty("os.version"));
- builder.appendField("coreCount", Runtime.getRuntime().availableProcessors());
- }
-
- private void appendServiceData(JsonObjectBuilder builder) {
- builder.appendField("pluginVersion", plugin.getDescription().getVersion());
- }
-
- private int getPlayerAmount() {
- try {
- // Around MC 1.8 the return type was changed from an array to a collection,
- // This fixes java.lang.NoSuchMethodError:
- // org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
- Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
- return onlinePlayersMethod.getReturnType().equals(Collection.class)
- ? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
- : ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
- } catch (Exception e) {
- // Just use the new method if the reflection failed
- return Bukkit.getOnlinePlayers().size();
- }
- }
-
- public static class MetricsBase {
-
- /** The version of the Metrics class. */
- public static final String METRICS_VERSION = "3.0.0";
-
- private static final ScheduledExecutorService scheduler =
- Executors.newScheduledThreadPool(1, task -> new Thread(task, "bStats-Metrics"));
-
- private static final String REPORT_URL = "https://bStats.org/api/v2/data/%s";
-
- private final String platform;
-
- private final String serverUuid;
-
- private final int serviceId;
-
- private final Consumer<JsonObjectBuilder> appendPlatformDataConsumer;
-
- private final Consumer<JsonObjectBuilder> appendServiceDataConsumer;
-
- private final Consumer<Runnable> submitTaskConsumer;
-
- private final Supplier<Boolean> checkServiceEnabledSupplier;
-
- private final BiConsumer<String, Throwable> errorLogger;
-
- private final Consumer<String> infoLogger;
-
- private final boolean logErrors;
-
- private final boolean logSentData;
-
- private final boolean logResponseStatusText;
-
- private final Set<CustomChart> customCharts = new HashSet<>();
-
- private final boolean enabled;
-
- /**
- * Creates a new MetricsBase class instance.
- *
- * @param platform The platform of the service.
- * @param serviceId The id of the service.
- * @param serverUuid The server uuid.
- * @param enabled Whether or not data sending is enabled.
- * @param appendPlatformDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
- * appends all platform-specific data.
- * @param appendServiceDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
- * appends all service-specific data.
- * @param submitTaskConsumer A consumer that takes a runnable with the submit task. This can be
- * used to delegate the data collection to a another thread to prevent errors caused by
- * concurrency. Can be {@code null}.
- * @param checkServiceEnabledSupplier A supplier to check if the service is still enabled.
- * @param errorLogger A consumer that accepts log message and an error.
- * @param infoLogger A consumer that accepts info log messages.
- * @param logErrors Whether or not errors should be logged.
- * @param logSentData Whether or not the sent data should be logged.
- * @param logResponseStatusText Whether or not the response status text should be logged.
- */
- public MetricsBase(
- String platform,
- String serverUuid,
- int serviceId,
- boolean enabled,
- Consumer<JsonObjectBuilder> appendPlatformDataConsumer,
- Consumer<JsonObjectBuilder> appendServiceDataConsumer,
- Consumer<Runnable> submitTaskConsumer,
- Supplier<Boolean> checkServiceEnabledSupplier,
- BiConsumer<String, Throwable> errorLogger,
- Consumer<String> infoLogger,
- boolean logErrors,
- boolean logSentData,
- boolean logResponseStatusText) {
- this.platform = platform;
- this.serverUuid = serverUuid;
- this.serviceId = serviceId;
- this.enabled = enabled;
- this.appendPlatformDataConsumer = appendPlatformDataConsumer;
- this.appendServiceDataConsumer = appendServiceDataConsumer;
- this.submitTaskConsumer = submitTaskConsumer;
- this.checkServiceEnabledSupplier = checkServiceEnabledSupplier;
- this.errorLogger = errorLogger;
- this.infoLogger = infoLogger;
- this.logErrors = logErrors;
- this.logSentData = logSentData;
- this.logResponseStatusText = logResponseStatusText;
- checkRelocation();
- if (enabled) {
- // WARNING: Removing the option to opt-out will get your plugin banned from bStats
- startSubmitting();
- }
- }
-
- public void addCustomChart(CustomChart chart) {
- this.customCharts.add(chart);
- }
-
- private void startSubmitting() {
- final Runnable submitTask =
- () -> {
- if (!enabled || !checkServiceEnabledSupplier.get()) {
- // Submitting data or service is disabled
- scheduler.shutdown();
- return;
- }
- if (submitTaskConsumer != null) {
- submitTaskConsumer.accept(this::submitData);
- } else {
- this.submitData();
- }
- };
- // Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution
- // of requests on the
- // bStats backend. To circumvent this problem, we introduce some randomness into the initial
- // and second delay.
- // WARNING: You must not modify and part of this Metrics class, including the submit delay or
- // frequency!
- // WARNING: Modifying this code will get your plugin banned on bStats. Just don't do it!
- long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3));
- long secondDelay = (long) (1000 * 60 * (Math.random() * 30));
- scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS);
- scheduler.scheduleAtFixedRate(
- submitTask, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
- }
-
- private void submitData() {
- final JsonObjectBuilder baseJsonBuilder = new JsonObjectBuilder();
- appendPlatformDataConsumer.accept(baseJsonBuilder);
- final JsonObjectBuilder serviceJsonBuilder = new JsonObjectBuilder();
- appendServiceDataConsumer.accept(serviceJsonBuilder);
- JsonObjectBuilder.JsonObject[] chartData =
- customCharts.stream()
- .map(customChart -> customChart.getRequestJsonObject(errorLogger, logErrors))
- .filter(Objects::nonNull)
- .toArray(JsonObjectBuilder.JsonObject[]::new);
- serviceJsonBuilder.appendField("id", serviceId);
- serviceJsonBuilder.appendField("customCharts", chartData);
- baseJsonBuilder.appendField("service", serviceJsonBuilder.build());
- baseJsonBuilder.appendField("serverUUID", serverUuid);
- baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION);
- JsonObjectBuilder.JsonObject data = baseJsonBuilder.build();
- scheduler.execute(
- () -> {
- try {
- // Send the data
- sendData(data);
- } catch (Exception e) {
- // Something went wrong! :(
- if (logErrors) {
- errorLogger.accept("Could not submit bStats metrics data", e);
- }
- }
- });
- }
-
- private void sendData(JsonObjectBuilder.JsonObject data) throws Exception {
- if (logSentData) {
- infoLogger.accept("Sent bStats metrics data: " + data.toString());
- }
- String url = String.format(REPORT_URL, platform);
- HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
- // Compress the data to save bandwidth
- byte[] compressedData = compress(data.toString());
- connection.setRequestMethod("POST");
- connection.addRequestProperty("Accept", "application/json");
- connection.addRequestProperty("Connection", "close");
- connection.addRequestProperty("Content-Encoding", "gzip");
- connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
- connection.setRequestProperty("Content-Type", "application/json");
- connection.setRequestProperty("User-Agent", "Metrics-Service/1");
- connection.setDoOutput(true);
- try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
- outputStream.write(compressedData);
- }
- StringBuilder builder = new StringBuilder();
- try (BufferedReader bufferedReader =
- new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
- String line;
- while ((line = bufferedReader.readLine()) != null) {
- builder.append(line);
- }
- }
- if (logResponseStatusText) {
- infoLogger.accept("Sent data to bStats and received response: " + builder);
- }
- }
-
- /** Checks that the class was properly relocated. */
- private void checkRelocation() {
- // 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'});
- final String examplePackage =
- new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
- // We want to make sure no one just copy & pastes the example and uses the wrong package
- // names
- if (MetricsBase.class.getPackage().getName().startsWith(defaultPackage)
- || MetricsBase.class.getPackage().getName().startsWith(examplePackage)) {
- throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
- }
- }
- }
-
- /**
- * Gzips the given string.
- *
- * @param str The string to gzip.
- * @return The gzipped string.
- */
- private static byte[] compress(final String str) throws IOException {
- if (str == null) {
- return null;
- }
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) {
- gzip.write(str.getBytes(StandardCharsets.UTF_8));
- }
- return outputStream.toByteArray();
- }
- }
-
- public static class DrilldownPie extends CustomChart {
-
- private final Callable<Map<String, Map<String, Integer>>> 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<Map<String, Map<String, Integer>>> callable) {
- super(chartId);
- this.callable = callable;
- }
-
- @Override
- public JsonObjectBuilder.JsonObject getChartData() throws Exception {
- JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
- Map<String, Map<String, Integer>> map = callable.call();
- if (map == null || map.isEmpty()) {
- // Null = skip the chart
- return null;
- }
- boolean reallyAllSkipped = true;
- for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
- JsonObjectBuilder valueBuilder = new JsonObjectBuilder();
- boolean allSkipped = true;
- for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
- valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue());
- allSkipped = false;
- }
- if (!allSkipped) {
- reallyAllSkipped = false;
- valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build());
- }
- }
- if (reallyAllSkipped) {
- // Null = skip the chart
- return null;
- }
- return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
- }
- }
-
- public static class AdvancedPie extends CustomChart {
-
- private final Callable<Map<String, Integer>> 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<Map<String, Integer>> callable) {
- super(chartId);
- this.callable = callable;
- }
-
- @Override
- protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
- JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
- Map<String, Integer> map = callable.call();
- if (map == null || map.isEmpty()) {
- // Null = skip the chart
- return null;
- }
- boolean allSkipped = true;
- for (Map.Entry<String, Integer> entry : map.entrySet()) {
- if (entry.getValue() == 0) {
- // Skip this invalid
- continue;
- }
- allSkipped = false;
- valuesBuilder.appendField(entry.getKey(), entry.getValue());
- }
- if (allSkipped) {
- // Null = skip the chart
- return null;
- }
- return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
- }
- }
-
- public static class MultiLineChart extends CustomChart {
-
- private final Callable<Map<String, Integer>> 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<Map<String, Integer>> callable) {
- super(chartId);
- this.callable = callable;
- }
-
- @Override
- protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
- JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
- Map<String, Integer> map = callable.call();
- if (map == null || map.isEmpty()) {
- // Null = skip the chart
- return null;
- }
- boolean allSkipped = true;
- for (Map.Entry<String, Integer> entry : map.entrySet()) {
- if (entry.getValue() == 0) {
- // Skip this invalid
- continue;
- }
- allSkipped = false;
- valuesBuilder.appendField(entry.getKey(), entry.getValue());
- }
- if (allSkipped) {
- // Null = skip the chart
- return null;
- }
- return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
- }
- }
-
- public static class SimpleBarChart extends CustomChart {
-
- private final Callable<Map<String, Integer>> 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<Map<String, Integer>> callable) {
- super(chartId);
- this.callable = callable;
- }
-
- @Override
- protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
- JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
- Map<String, Integer> map = callable.call();
- if (map == null || map.isEmpty()) {
- // Null = skip the chart
- return null;
- }
- for (Map.Entry<String, Integer> entry : map.entrySet()) {
- valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()});
- }
- return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
- }
- }
-
- public abstract static class CustomChart {
-
- private final String chartId;
-
- protected CustomChart(String chartId) {
- if (chartId == null) {
- throw new IllegalArgumentException("chartId must not be null");
- }
- this.chartId = chartId;
- }
-
- public JsonObjectBuilder.JsonObject getRequestJsonObject(
- BiConsumer<String, Throwable> errorLogger, boolean logErrors) {
- JsonObjectBuilder builder = new JsonObjectBuilder();
- builder.appendField("chartId", chartId);
- try {
- JsonObjectBuilder.JsonObject data = getChartData();
- if (data == null) {
- // If the data is null we don't send the chart.
- return null;
- }
- builder.appendField("data", data);
- } catch (Throwable t) {
- if (logErrors) {
- errorLogger.accept("Failed to get data for custom chart with id " + chartId, t);
- }
- return null;
- }
- return builder.build();
- }
-
- protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception;
- }
-
- public static class SimplePie extends CustomChart {
-
- private final Callable<String> 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<String> callable) {
- super(chartId);
- this.callable = callable;
- }
-
- @Override
- protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
- String value = callable.call();
- if (value == null || value.isEmpty()) {
- // Null = skip the chart
- return null;
- }
- return new JsonObjectBuilder().appendField("value", value).build();
- }
- }
-
- public static class AdvancedBarChart extends CustomChart {
-
- private final Callable<Map<String, int[]>> 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<Map<String, int[]>> callable) {
- super(chartId);
- this.callable = callable;
- }
-
- @Override
- protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
- JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
- Map<String, int[]> map = callable.call();
- if (map == null || map.isEmpty()) {
- // Null = skip the chart
- return null;
- }
- boolean allSkipped = true;
- for (Map.Entry<String, int[]> entry : map.entrySet()) {
- if (entry.getValue().length == 0) {
- // Skip this invalid
- continue;
- }
- allSkipped = false;
- valuesBuilder.appendField(entry.getKey(), entry.getValue());
- }
- if (allSkipped) {
- // Null = skip the chart
- return null;
- }
- return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
- }
- }
-
- public static class SingleLineChart extends CustomChart {
-
- private final Callable<Integer> 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<Integer> callable) {
- super(chartId);
- this.callable = callable;
- }
-
- @Override
- protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
- int value = callable.call();
- if (value == 0) {
- // Null = skip the chart
- return null;
- }
- return new JsonObjectBuilder().appendField("value", value).build();
- }
- }
-
- /**
- * An extremely simple JSON builder.
- *
- * <p>While this class is neither feature-rich nor the most performant one, it's sufficient enough
- * for its use-case.
- */
- public static class JsonObjectBuilder {
-
- private StringBuilder builder = new StringBuilder();
-
- private boolean hasAtLeastOneField = false;
-
- public JsonObjectBuilder() {
- builder.append("{");
- }
-
- /**
- * Appends a null field to the JSON.
- *
- * @param key The key of the field.
- * @return A reference to this object.
- */
- public JsonObjectBuilder appendNull(String key) {
- appendFieldUnescaped(key, "null");
- return this;
- }
-
- /**
- * Appends a string field to the JSON.
- *
- * @param key The key of the field.
- * @param value The value of the field.
- * @return A reference to this object.
- */
- public JsonObjectBuilder appendField(String key, String value) {
- if (value == null) {
- throw new IllegalArgumentException("JSON value must not be null");
- }
- appendFieldUnescaped(key, "\"" + escape(value) + "\"");
- return this;
- }
-
- /**
- * Appends an integer field to the JSON.
- *
- * @param key The key of the field.
- * @param value The value of the field.
- * @return A reference to this object.
- */
- public JsonObjectBuilder appendField(String key, int value) {
- appendFieldUnescaped(key, String.valueOf(value));
- return this;
- }
-
- /**
- * Appends an object to the JSON.
- *
- * @param key The key of the field.
- * @param object The object.
- * @return A reference to this object.
- */
- public JsonObjectBuilder appendField(String key, JsonObject object) {
- if (object == null) {
- throw new IllegalArgumentException("JSON object must not be null");
- }
- appendFieldUnescaped(key, object.toString());
- return this;
- }
-
- /**
- * Appends a string array to the JSON.
- *
- * @param key The key of the field.
- * @param values The string array.
- * @return A reference to this object.
- */
- public JsonObjectBuilder appendField(String key, String[] values) {
- if (values == null) {
- throw new IllegalArgumentException("JSON values must not be null");
- }
- String escapedValues =
- Arrays.stream(values)
- .map(value -> "\"" + escape(value) + "\"")
- .collect(Collectors.joining(","));
- appendFieldUnescaped(key, "[" + escapedValues + "]");
- return this;
- }
-
- /**
- * Appends an integer array to the JSON.
- *
- * @param key The key of the field.
- * @param values The integer array.
- * @return A reference to this object.
- */
- public JsonObjectBuilder appendField(String key, int[] values) {
- if (values == null) {
- throw new IllegalArgumentException("JSON values must not be null");
- }
- String escapedValues =
- Arrays.stream(values).mapToObj(String::valueOf).collect(Collectors.joining(","));
- appendFieldUnescaped(key, "[" + escapedValues + "]");
- return this;
- }
-
- /**
- * Appends an object array to the JSON.
- *
- * @param key The key of the field.
- * @param values The integer array.
- * @return A reference to this object.
- */
- public JsonObjectBuilder appendField(String key, JsonObject[] values) {
- if (values == null) {
- throw new IllegalArgumentException("JSON values must not be null");
- }
- String escapedValues =
- Arrays.stream(values).map(JsonObject::toString).collect(Collectors.joining(","));
- appendFieldUnescaped(key, "[" + escapedValues + "]");
- return this;
- }
-
- /**
- * Appends a field to the object.
- *
- * @param key The key of the field.
- * @param escapedValue The escaped value of the field.
- */
- private void appendFieldUnescaped(String key, String escapedValue) {
- if (builder == null) {
- throw new IllegalStateException("JSON has already been built");
- }
- if (key == null) {
- throw new IllegalArgumentException("JSON key must not be null");
- }
- if (hasAtLeastOneField) {
- builder.append(",");
- }
- builder.append("\"").append(escape(key)).append("\":").append(escapedValue);
- hasAtLeastOneField = true;
- }
-
- /**
- * Builds the JSON string and invalidates this builder.
- *
- * @return The built JSON string.
- */
- public JsonObject build() {
- if (builder == null) {
- throw new IllegalStateException("JSON has already been built");
- }
- JsonObject object = new JsonObject(builder.append("}").toString());
- builder = null;
- return object;
- }
-
- /**
- * Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt.
- *
- * <p>This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'.
- * Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n").
- *
- * @param value The value to escape.
- * @return The escaped value.
- */
- private static String escape(String value) {
- final StringBuilder builder = new StringBuilder();
- for (int i = 0; i < value.length(); i++) {
- char c = value.charAt(i);
- if (c == '"') {
- builder.append("\\\"");
- } else if (c == '\\') {
- builder.append("\\\\");
- } else if (c <= '\u000F') {
- builder.append("\\u000").append(Integer.toHexString(c));
- } else if (c <= '\u001F') {
- builder.append("\\u00").append(Integer.toHexString(c));
- } else {
- builder.append(c);
- }
- }
- return builder.toString();
- }
-
- /**
- * A super simple representation of a JSON object.
- *
- * <p>This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and not
- * allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String,
- * JsonObject)}.
- */
- public static class JsonObject {
-
- private final String value;
-
- private JsonObject(String value) {
- this.value = value;
- }
-
- @Override
- public String toString() {
- return value;
- }
- }
- }
-}