From 83176d863191f5357186a1b99d1bb8b1c63cf06c Mon Sep 17 00:00:00 2001 From: KillerOfPie Date: Mon, 3 Jan 2022 17:50:08 -0800 Subject: [PATCH] Added Custom Setting and Usage Metrics - Added Metrics Managed to clean up adding of custom metric charts - Fixed Potential bug in DataStorage#getShopCountInWorld where worlds(like the nether and end) that exist without shops would throw null if checked - Fixed bad array count in ShopChunk#deserialize - Added trade count so metrics can be sent on the amount of trades --- .../java/org/shanerx/tradeshop/TradeShop.java | 20 +- .../listeners/ShopTradeListener.java | 2 + .../shanerx/tradeshop/objects/ShopChunk.java | 2 +- .../tradeshop/utils/MetricsManager.java | 277 ++++++++++++++++++ .../tradeshop/utils/data/DataStorage.java | 9 +- 5 files changed, 297 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/shanerx/tradeshop/utils/MetricsManager.java diff --git a/src/main/java/org/shanerx/tradeshop/TradeShop.java b/src/main/java/org/shanerx/tradeshop/TradeShop.java index b14be19d..c159557b 100644 --- a/src/main/java/org/shanerx/tradeshop/TradeShop.java +++ b/src/main/java/org/shanerx/tradeshop/TradeShop.java @@ -25,7 +25,6 @@ package org.shanerx.tradeshop; -import org.bstats.bukkit.Metrics; import org.bukkit.NamespacedKey; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; @@ -45,6 +44,7 @@ import org.shanerx.tradeshop.objects.ListManager; import org.shanerx.tradeshop.utils.BukkitVersion; import org.shanerx.tradeshop.utils.Expirer; +import org.shanerx.tradeshop.utils.MetricsManager; import org.shanerx.tradeshop.utils.Updater; import org.shanerx.tradeshop.utils.data.DataStorage; import org.shanerx.tradeshop.utils.data.DataType; @@ -56,8 +56,7 @@ public class TradeShop extends JavaPlugin { private final NamespacedKey storageKey = new NamespacedKey(this, "tradeshop-storage-data"); private final NamespacedKey signKey = new NamespacedKey(this, "tradeshop-sign-data"); - private final int bStatsPluginID = 1690; - private Metrics metrics; + private MetricsManager metricsManager; private boolean useInternalPerms = false; @@ -123,9 +122,8 @@ public void onEnable() { } if (Setting.ALLOW_METRICS.getBoolean()) { - metrics = new Metrics(this, bStatsPluginID); + metricsManager = new MetricsManager(this); getLogger().info("Metrics successfully initialized!"); - } else { getLogger().warning("Metrics are disabled! Please consider enabling them to support the authors!"); } @@ -172,13 +170,17 @@ public ShopStorage getStorages() { public Updater getUpdater() { return new Updater(getDescription(), "https://api.spigotmc.org/legacy/update.php?resource=32762", "https://www.spigotmc.org/resources/tradeshop.32762/"); - } + } - public Debug getDebugger() { - return debugger; - } + public Debug getDebugger() { + return debugger; + } public DataStorage getDataStorage() { return dataStorage; } + + public MetricsManager getMetricsManager() { + return metricsManager; + } } diff --git a/src/main/java/org/shanerx/tradeshop/listeners/ShopTradeListener.java b/src/main/java/org/shanerx/tradeshop/listeners/ShopTradeListener.java index 09c1985a..f8f16743 100644 --- a/src/main/java/org/shanerx/tradeshop/listeners/ShopTradeListener.java +++ b/src/main/java/org/shanerx/tradeshop/listeners/ShopTradeListener.java @@ -258,6 +258,7 @@ private boolean tradeAllItems(Shop shop, int multiplier, PlayerInteractEvent eve } Bukkit.getPluginManager().callEvent(new PlayerSuccessfulTradeEvent(buyer, costItems, productItems, shop, event.getClickedBlock(), event.getBlockFace())); + plugin.getMetricsManager().addTrade(); return true; //Successfully completed trade } else if (shop.getShopType() == ShopType.BITRADE && action == Action.LEFT_CLICK_BLOCK) { //BiTrade Reversed Trade @@ -328,6 +329,7 @@ private boolean tradeAllItems(Shop shop, int multiplier, PlayerInteractEvent eve } Bukkit.getPluginManager().callEvent(new PlayerSuccessfulTradeEvent(buyer, costItems, productItems, shop, event.getClickedBlock(), event.getBlockFace())); + plugin.getMetricsManager().addTrade(); return true; //Successfully completed trade } else { return false; diff --git a/src/main/java/org/shanerx/tradeshop/objects/ShopChunk.java b/src/main/java/org/shanerx/tradeshop/objects/ShopChunk.java index ff20946e..80dfdab2 100644 --- a/src/main/java/org/shanerx/tradeshop/objects/ShopChunk.java +++ b/src/main/java/org/shanerx/tradeshop/objects/ShopChunk.java @@ -59,7 +59,7 @@ public static Chunk deserialize(String loc) { World world = Bukkit.getWorld(locA[1]); if (world == null) world = Bukkit.getWorld(locA[1].replace("-", "_")); - int x = Integer.parseInt(locA[2]), z = Integer.parseInt(locA[4]); + int x = Integer.parseInt(locA[2]), z = Integer.parseInt(locA[3]); return world.getChunkAt(x, z); } diff --git a/src/main/java/org/shanerx/tradeshop/utils/MetricsManager.java b/src/main/java/org/shanerx/tradeshop/utils/MetricsManager.java new file mode 100644 index 00000000..19b8d208 --- /dev/null +++ b/src/main/java/org/shanerx/tradeshop/utils/MetricsManager.java @@ -0,0 +1,277 @@ +/* + * + * Copyright (c) 2016-2019 + * SparklingComet @ http://shanerx.org + * KillerOfPie @ http://killerofpie.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE: All modifications made by others to the source code belong + * to the respective contributor. No contributor should be held liable for + * any damages of any kind, whether be material or moral, which were + * caused by their contribution(s) to the project. See the full License for more information. + * + */ + +package org.shanerx.tradeshop.utils; + +import org.bstats.bukkit.Metrics; +import org.bstats.charts.AdvancedBarChart; +import org.bstats.charts.AdvancedPie; +import org.bstats.charts.SimpleBarChart; +import org.bstats.charts.SimplePie; +import org.bstats.charts.SingleLineChart; +import org.bukkit.World; +import org.shanerx.tradeshop.TradeShop; +import org.shanerx.tradeshop.enumys.Setting; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; + +public class MetricsManager { + private final int bStatsPluginID = 1690; + private final TradeShop plugin; + private final Metrics metrics; + private int tradeCounter = 0; + + public MetricsManager(TradeShop plugin) { + this.plugin = plugin; + metrics = new Metrics(plugin, bStatsPluginID); + + addTradeMetric(); + addShopMetric(); + addOtherSettingMetrics(); + + // Add to bstats when Bar Charts are re-added + addFeatureMetric(); + addIllegalItemsBarMetric(); + addSettingStringListMetrics(); + + // Remove when above are added + addFeaturePieMetrics(); + addSettingStringListAdvancedPieMetrics(); + addIllegalItemsPieMetric(); + } + + public void addTrade() { + tradeCounter++; + } + + private void addTradeMetric() { + metrics.addCustomChart(new SingleLineChart("trade-counter", new Callable() { + @Override + public Integer call() throws Exception { + int count = tradeCounter; + tradeCounter = 0; + return count; + } + })); + } + + private void addShopMetric() { + metrics.addCustomChart(new SingleLineChart("shop-counter", new Callable() { + @Override + public Integer call() throws Exception { + int count = 0; + for (World world : plugin.getServer().getWorlds()) { + count += plugin.getDataStorage().getShopCountInWorld(world); + } + return count; + } + })); + } + + private void addFeatureMetric() { + metrics.addCustomChart(new AdvancedBarChart("feature-status", new Callable>() { + @Override + public Map call() throws Exception { + Map map = new HashMap<>(); + List booleanSettingList = Arrays.asList(Setting.CHECK_UPDATES, + Setting.UNLIMITED_ADMIN, + Setting.USE_INTERNAL_PERMISSIONS, + Setting.ALLOW_TOGGLE_STATUS, + Setting.ALLOW_SIGN_BREAK, + Setting.ALLOW_CHEST_BREAK, + Setting.ALLOW_MULTI_TRADE, + Setting.ALLOW_USER_PURCHASING, + Setting.TRADESHOP_EXPLODE, + Setting.TRADESHOP_HOPPER_EXPORT, + Setting.TRADESHOP_HOPPER_IMPORT, + Setting.ITRADESHOP_EXPLODE, + Setting.BITRADESHOP_EXPLODE, + Setting.BITRADESHOP_HOPPER_EXPORT, + Setting.BITRADESHOP_HOPPER_IMPORT); + + for (Setting setting : booleanSettingList) { + if (setting.getBoolean()) { + map.put(setting.name(), new int[]{0, 1}); + } else { + map.put(setting.name(), new int[]{1, 0}); + } + } + + return map; + } + })); + } + + private void addIllegalItemsBarMetric() { + metrics.addCustomChart(new AdvancedBarChart("illegal-item-types", new Callable>() { + @Override + public Map call() throws Exception { + Map map = new HashMap<>(); + + switch (plugin.getListManager().getGlobalList().getType()) { + case BLACKLIST: + map.put("General List", new int[]{1, 0, 0}); + break; + case WHITELIST: + map.put("General List", new int[]{0, 1, 0}); + break; + case DISABLED: + default: + map.put("General List", new int[]{0, 0, 1}); + break; + } + + switch (plugin.getListManager().getCostList().getType()) { + case BLACKLIST: + map.put("Cost List", new int[]{1, 0, 0}); + break; + case WHITELIST: + map.put("Cost List", new int[]{0, 1, 0}); + break; + case DISABLED: + default: + map.put("Cost List", new int[]{0, 0, 1}); + break; + } + + switch (plugin.getListManager().getProductList().getType()) { + case BLACKLIST: + map.put("Product List", new int[]{1, 0, 0}); + break; + case WHITELIST: + map.put("Product List", new int[]{0, 1, 0}); + break; + case DISABLED: + default: + map.put("Product List", new int[]{0, 0, 1}); + break; + } + return map; + } + })); + } + + private void addSettingStringListMetrics() { + List settingList = Arrays.asList(Setting.ALLOWED_DIRECTIONS, + Setting.ALLOWED_SHOPS); + + for (Setting setting : settingList) { + metrics.addCustomChart(new SimpleBarChart(setting.name().toLowerCase().replace("_", "-") + "-list", new Callable>() { + @Override + public Map call() throws Exception { + Map map = new HashMap<>(); + + for (String string : setting.getStringList()) { + map.put(string, 1); + } + + return map; + } + })); + } + } + + private void addOtherSettingMetrics() { + metrics.addCustomChart(new SimplePie("data-storage-type", Setting.DATA_STORAGE_TYPE::getString)); + + metrics.addCustomChart(new SimplePie("max-shop-users", () -> { + return String.valueOf(Setting.MAX_SHOP_USERS.getInt()); + })); + + metrics.addCustomChart(new SimplePie("max-shops-per-chunk", () -> { + return String.valueOf(Setting.MAX_SHOPS_PER_CHUNK.getInt()); + })); + + metrics.addCustomChart(new SimplePie("max-items-per-trade-side", () -> { + return String.valueOf(Setting.MAX_ITEMS_PER_TRADE_SIDE.getInt()); + })); + + + } + + + // Temporary solutions while Bar graphs are unavailable + private void addFeaturePieMetrics() { + List booleanSettingList = Arrays.asList(Setting.CHECK_UPDATES, + Setting.UNLIMITED_ADMIN, + Setting.USE_INTERNAL_PERMISSIONS, + Setting.ALLOW_TOGGLE_STATUS, + Setting.ALLOW_SIGN_BREAK, + Setting.ALLOW_CHEST_BREAK, + Setting.ALLOW_MULTI_TRADE, + Setting.ALLOW_USER_PURCHASING, + Setting.TRADESHOP_EXPLODE, + Setting.TRADESHOP_HOPPER_EXPORT, + Setting.TRADESHOP_HOPPER_IMPORT, + Setting.ITRADESHOP_EXPLODE, + Setting.BITRADESHOP_EXPLODE, + Setting.BITRADESHOP_HOPPER_EXPORT, + Setting.BITRADESHOP_HOPPER_IMPORT); + + for (Setting setting : booleanSettingList) { + metrics.addCustomChart(new SimplePie(setting.name().toLowerCase(), () -> { + return String.valueOf(setting.getBoolean()); + })); + } + } + + private void addSettingStringListAdvancedPieMetrics() { + List settingList = Arrays.asList(Setting.ALLOWED_DIRECTIONS, + Setting.ALLOWED_SHOPS); + + for (Setting setting : settingList) { + metrics.addCustomChart(new AdvancedPie(setting.name().toLowerCase(), new Callable>() { + @Override + public Map call() throws Exception { + Map map = new HashMap<>(); + + for (String string : setting.getStringList()) { + map.put(string, 1); + } + + return map; + } + })); + } + } + + private void addIllegalItemsPieMetric() { + metrics.addCustomChart(new SimplePie("illegal-items-global-type", () -> { + return plugin.getListManager().getGlobalList().getType().toString(); + })); + metrics.addCustomChart(new SimplePie("illegal-items-cost-type", () -> { + return plugin.getListManager().getCostList().getType().toString(); + })); + metrics.addCustomChart(new SimplePie("illegal-items-product-type", () -> { + return plugin.getListManager().getProductList().getType().toString(); + })); + } + + +} diff --git a/src/main/java/org/shanerx/tradeshop/utils/data/DataStorage.java b/src/main/java/org/shanerx/tradeshop/utils/data/DataStorage.java index 93ac0795..ce4e73a3 100644 --- a/src/main/java/org/shanerx/tradeshop/utils/data/DataStorage.java +++ b/src/main/java/org/shanerx/tradeshop/utils/data/DataStorage.java @@ -39,7 +39,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.Objects; import java.util.UUID; public class DataStorage extends Utils { @@ -112,8 +111,12 @@ public int getShopCountInWorld(World world) { int count = 0; switch (dataType) { case FLATFILE: - for (File file : Objects.requireNonNull(new File(plugin.getDataFolder().getAbsolutePath() + File.separator + "Data" + File.separator + world.getName()).listFiles())) { - count += new JsonConfiguration(ShopChunk.deserialize(file.getName().replace(".json", ""))).getShopCount(); + File folder = new File(plugin.getDataFolder().getAbsolutePath() + File.separator + "Data" + File.separator + world.getName()); + if (folder.exists() && folder.listFiles() != null) { + for (File file : folder.listFiles()) { + if (file.getName().contains(world.getName())) + count += new JsonConfiguration(ShopChunk.deserialize(file.getName().replace(".json", ""))).getShopCount(); + } } break; case SQLITE: