diff --git a/pom.xml b/pom.xml index 69faafbaa..c03b5cc90 100755 --- a/pom.xml +++ b/pom.xml @@ -64,6 +64,19 @@ org.apache.maven.plugins maven-shade-plugin 1.5 + + + + com.turt2live.metrics:MetricsExtension + + + + + com.turt2live.metrics + com.gmail.nossr50.metrics.mcstats + + + package @@ -87,6 +100,10 @@ bukkit-repo http://repo.bukkit.org/content/groups/public/ + + Plugin MetricsExtension + http://repo.turt2live.com + @@ -102,6 +119,11 @@ 4.10 test + + com.turt2live.metrics + MetricsExtension + 0.0.5-SNAPSHOT + diff --git a/src/main/java/com/gmail/nossr50/config/AutoUpdateConfigLoader.java b/src/main/java/com/gmail/nossr50/config/AutoUpdateConfigLoader.java index 4e7206ac7..111a5fecc 100644 --- a/src/main/java/com/gmail/nossr50/config/AutoUpdateConfigLoader.java +++ b/src/main/java/com/gmail/nossr50/config/AutoUpdateConfigLoader.java @@ -12,6 +12,8 @@ import java.util.Set; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; +import com.gmail.nossr50.metrics.MetricsManager; + public abstract class AutoUpdateConfigLoader extends ConfigLoader { public AutoUpdateConfigLoader(String relativePath, String fileName) { super(relativePath, fileName); @@ -117,6 +119,7 @@ public abstract class AutoUpdateConfigLoader extends ConfigLoader { else { for (String key : configKeys) { if (!config.isConfigurationSection(key) && !config.get(key).equals(internalConfig.get(key))) { + MetricsManager.customConfig(); break; } } diff --git a/src/main/java/com/gmail/nossr50/config/Config.java b/src/main/java/com/gmail/nossr50/config/Config.java index dba206515..f56c6a226 100644 --- a/src/main/java/com/gmail/nossr50/config/Config.java +++ b/src/main/java/com/gmail/nossr50/config/Config.java @@ -182,6 +182,7 @@ public class Config extends AutoUpdateConfigLoader { public boolean getMOTDEnabled() { return config.getBoolean("General.MOTD_Enabled", true); } public boolean getDonateMessageEnabled() { return config.getBoolean("Commands.mcmmo.Donate_Message", true); } public int getSaveInterval() { return config.getInt("General.Save_Interval", 10); } + public boolean getStatsTrackingEnabled() { return config.getBoolean("General.Stats_Tracking", true); } public boolean getUpdateCheckEnabled() { return config.getBoolean("General.Update_Check", true); } public boolean getPreferBeta() { return config.getBoolean("General.Prefer_Beta", false); } public boolean getEventCallbackEnabled() { return config.getBoolean("General.Event_Callback", true); } diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index bf788d98f..b18f9e217 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -28,6 +28,7 @@ import com.gmail.nossr50.listeners.PlayerListener; import com.gmail.nossr50.listeners.SelfListener; import com.gmail.nossr50.listeners.WorldListener; import com.gmail.nossr50.locale.LocaleLoader; +import com.gmail.nossr50.metrics.MetricsManager; import com.gmail.nossr50.party.PartyManager; import com.gmail.nossr50.runnables.SaveTimerTask; import com.gmail.nossr50.runnables.database.UserPurgeTask; @@ -141,6 +142,8 @@ public class mcMMO extends JavaPlugin { scheduleTasks(); CommandRegistrationManager.registerCommands(); + MetricsManager.setup(); + placeStore = ChunkManagerFactory.getChunkManager(); // Get our ChunkletManager checkForUpdates(); diff --git a/src/main/java/com/gmail/nossr50/metrics/MetricsManager.java b/src/main/java/com/gmail/nossr50/metrics/MetricsManager.java new file mode 100644 index 000000000..313db4617 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/metrics/MetricsManager.java @@ -0,0 +1,355 @@ +package com.gmail.nossr50.metrics; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Locale; + +import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.config.Config; +import com.gmail.nossr50.config.HiddenConfig; +import com.gmail.nossr50.config.experience.ExperienceConfig; +import com.gmail.nossr50.datatypes.experience.FormulaType; +import com.gmail.nossr50.locale.LocaleLoader; + +import com.turt2live.metrics.EMetrics; +import com.turt2live.metrics.Metrics; +import com.turt2live.metrics.Metrics.Graph; +import com.turt2live.metrics.data.DataEvent; +import com.turt2live.metrics.data.DataTracker; +import com.turt2live.metrics.tracker.Tracker; + +public class MetricsManager { + private static boolean setup = false; + + private static Tracker chimeraUseTracker; + private static Tracker chimeraServerUseTracker; + + private static boolean customConfig = false; + + private static DataTracker tracker; + private static EMetrics emetrics; + + public static void setup() { + if (setup) { + return; + } + + if (Config.getInstance().getStatsTrackingEnabled()) { + try { + emetrics = new EMetrics(mcMMO.p); + Metrics metrics = emetrics.getMetrics(); + + // Timings Graph + Graph timingsGraph = metrics.createGraph("Percentage of servers using timings"); + + if (mcMMO.p.getServer().getPluginManager().useTimings()) { + timingsGraph.addPlotter(new Metrics.Plotter("Enabled") { + @Override + public int getValue() { + return 1; + } + }); + } + else { + timingsGraph.addPlotter(new Metrics.Plotter("Disabled") { + @Override + public int getValue() { + return 1; + } + }); + } + + // Donut Version Graph + Graph versionDonutGraph = metrics.createGraph("Donut Version"); + + boolean haveVersionInformation = false; + boolean isOfficialBuild = false; + String officialKey = "e14cfacdd442a953343ebd8529138680"; + + String version = mcMMO.p.getDescription().getVersion(); + + InputStreamReader isr = new InputStreamReader(mcMMO.p.getResource(".jenkins")); + BufferedReader br = new BufferedReader(isr); + char[] key = new char[32]; + br.read(key); + if (officialKey.equals(String.valueOf(key))) { + isOfficialBuild = true; + } + + if (version.contains("-")) { + String majorVersion = version.substring(0, version.indexOf("-")); + String subVersion = ""; + if (isOfficialBuild) { + int startIndex = version.indexOf("-"); + if (version.substring(startIndex + 1).contains("-")) { + subVersion = version.substring(startIndex, version.indexOf("-", startIndex + 1)); + } + else { + subVersion = "-release"; + } + } + else { + subVersion = "-custom"; + } + + version = majorVersion + "~=~" + subVersion; + haveVersionInformation = true; + } + else { + haveVersionInformation = false; + } + + if (haveVersionInformation) { + versionDonutGraph.addPlotter(new Metrics.Plotter(version) { + @Override + public int getValue() { + return 1; + } + }); + } + + // Official v Custom build Graph + Graph officialGraph = metrics.createGraph("Built by official ci"); + + if (isOfficialBuild) { + officialGraph.addPlotter(new Metrics.Plotter("Yes") { + @Override + public int getValue() { + return 1; + } + }); + } + else { + officialGraph.addPlotter(new Metrics.Plotter("No") { + @Override + public int getValue() { + return 1; + } + }); + } + + // Chunkmeta enabled Graph + Graph chunkmetaGraph = metrics.createGraph("Uses Chunkmeta"); + + if (HiddenConfig.getInstance().getChunkletsEnabled()) { + chunkmetaGraph.addPlotter(new Metrics.Plotter("Yes") { + @Override + public int getValue() { + return 1; + } + }); + } + else { + chunkmetaGraph.addPlotter(new Metrics.Plotter("No") { + @Override + public int getValue() { + return 1; + } + }); + } + + // Storage method Graph + Graph storageGraph = metrics.createGraph("Storage method"); + + if (Config.getInstance().getUseMySQL()) { + storageGraph.addPlotter(new Metrics.Plotter("SQL") { + @Override + public int getValue() { + return 1; + } + }); + } + else { + storageGraph.addPlotter(new Metrics.Plotter("Flatfile") { + @Override + public int getValue() { + return 1; + } + }); + } + + // Locale Graph + Graph localeGraph = metrics.createGraph("Locale"); + + localeGraph.addPlotter(new Metrics.Plotter(LocaleLoader.getCurrentLocale().getDisplayLanguage(Locale.US)) { + @Override + public int getValue() { + return 1; + } + }); + + // ExperienceFormulaShape Graph + Graph experienceFormulaShapeGraph = metrics.createGraph("Experience Formula Shape Graph"); + + experienceFormulaShapeGraph.addPlotter(new Metrics.Plotter(ExperienceConfig.getInstance().getFormulaType().toString()) { + @Override + public int getValue() { + return 1; + } + }); + + // GlobalMultiplier Graph + Graph globalMultiplierGraph = metrics.createGraph("Global Multiplier Graph"); + + globalMultiplierGraph.addPlotter(new Metrics.Plotter(ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier() + "") { + @Override + public int getValue() { + return 1; + } + }); + + // GlobalCurveModifier Graph + Graph globalCurveModifierGraph = metrics.createGraph("Global Curve Modifier Graph"); + + globalCurveModifierGraph.addPlotter(new Metrics.Plotter(ExperienceConfig.getInstance().getMultiplier(FormulaType.LINEAR) + "") { + @Override + public int getValue() { + return 1; + } + }); + + // GlobalMultiplierGraph Fuzzy Logic Numbers + Graph globalMultiplierGraphFuzzy = metrics.createGraph("Global Multiplier Fuzz"); + + if (ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier() > 1.0) { + globalMultiplierGraphFuzzy.addPlotter(new Metrics.Plotter("Higher") { + @Override + public int getValue() { + return 1; + } + }); + } + else if (ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier() < 1.0) { + globalMultiplierGraphFuzzy.addPlotter(new Metrics.Plotter("Lower") { + @Override + public int getValue() { + return 1; + } + }); + } + else { + globalMultiplierGraphFuzzy.addPlotter(new Metrics.Plotter("Default") { + @Override + public int getValue() { + return 1; + } + }); + } + + // GlobalCurveModifier Fuzzy Logic Numbers + Graph globalCurveMultiplierGraphFuzzy = metrics.createGraph("Global Curve Multiplier Fuzz"); + + if (ExperienceConfig.getInstance().getMultiplier(FormulaType.LINEAR) > 20.0) { + globalCurveMultiplierGraphFuzzy.addPlotter(new Metrics.Plotter("Higher") { + @Override + public int getValue() { + return 1; + } + }); + } + else if (ExperienceConfig.getInstance().getMultiplier(FormulaType.LINEAR) < 20.0) { + globalCurveMultiplierGraphFuzzy.addPlotter(new Metrics.Plotter("Lower") { + @Override + public int getValue() { + return 1; + } + }); + } + else { + globalCurveMultiplierGraphFuzzy.addPlotter(new Metrics.Plotter("Default") { + @Override + public int getValue() { + return 1; + } + }); + } + + // Chimera Wing Usage Trackers + final String chimeraGraphName = "Chimera Wing Usage"; + + chimeraUseTracker = EMetrics.createBasicTracker(chimeraGraphName, "Player use"); + chimeraServerUseTracker = EMetrics.createEnabledTracker(chimeraGraphName, "Server use"); + + emetrics.addTracker(chimeraUseTracker); + emetrics.addTracker(chimeraServerUseTracker); + + // Chimera Wing Enabled Graph + Graph chimeraGraph = metrics.createGraph("Chimera Wing"); + + if (Config.getInstance().getChimaeraEnabled()) { + chimeraGraph.addPlotter(new Metrics.Plotter("Enabled") { + @Override + public int getValue() { + return 1; + } + }); + } + else { + chimeraGraph.addPlotter(new Metrics.Plotter("Disabled") { + @Override + public int getValue() { + return 1; + } + }); + } + + // Vanilla v Modified config graph + Graph customConfigGraph = metrics.createGraph("Modified Configs"); + + if (customConfig) { + customConfigGraph.addPlotter(new Metrics.Plotter("Edited") { + @Override + public int getValue() { + return 1; + } + }); + } + else { + customConfigGraph.addPlotter(new Metrics.Plotter("Vanilla") { + @Override + public int getValue() { + return 1; + } + }); + } + + /* + * Debug stuff + * tracker = emetrics.getDataTracker(); + * tracker.enable(); + * tracker.setFilter(new DataEvent.DataType [] { DataEvent.DataType.SEND_DATA }); + */ + + emetrics.startMetrics(); + } + catch (IOException e) { + mcMMO.p.getLogger().warning("Failed to submit stats."); + } + } + } + + public static void chimeraWingUsed() { + chimeraUseTracker.increment(); + chimeraServerUseTracker.increment(); + } + + public static void customConfig() { + customConfig = true; + } + + @SuppressWarnings("unused") + private static void debug() { + emetrics.getMetrics().flush(); + + for (DataEvent event : tracker.getEvents()) { + String graphName = event.getGraphName(); + String colName = event.getTrackerName(); + int value = event.getValueSent(); + + System.out.println("Graph: " + graphName + ", Column: " + colName + ", Value: " + value); + } + + tracker.resetEvents(); + } +} diff --git a/src/main/java/com/gmail/nossr50/util/ChimaeraWing.java b/src/main/java/com/gmail/nossr50/util/ChimaeraWing.java index 832dda3dd..f888b6ae1 100644 --- a/src/main/java/com/gmail/nossr50/util/ChimaeraWing.java +++ b/src/main/java/com/gmail/nossr50/util/ChimaeraWing.java @@ -17,6 +17,7 @@ import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.config.Config; import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.locale.LocaleLoader; +import com.gmail.nossr50.metrics.MetricsManager; import com.gmail.nossr50.runnables.items.ChimaeraWingWarmup; import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.skills.CombatUtils; @@ -133,6 +134,9 @@ public final class ChimaeraWing { player.updateInventory(); mcMMOPlayer.actualizeChimeraWingLastUse(); mcMMOPlayer.setTeleportCommenceLocation(null); + if (Config.getInstance().getStatsTrackingEnabled()) { + MetricsManager.chimeraWingUsed(); + } player.playSound(location, Sound.BAT_TAKEOFF, Misc.BAT_VOLUME, Misc.BAT_PITCH); player.sendMessage(LocaleLoader.getString("Item.ChimaeraWing.Pass")); } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 9ef5b5c76..ea76e7a14 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -12,6 +12,8 @@ General: MOTD_Enabled: true # Amount of time (in minutes) to wait between saves of player information Save_Interval: 10 + # Allow mcMMO to report on basic anonymous usage + Stats_Tracking: true # Allow mcMMO to check if a new version is available Update_Check: true Prefer_Beta: false