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