diff --git a/README.md b/README.md
index 6865a58..8015b40 100644
--- a/README.md
+++ b/README.md
@@ -71,3 +71,11 @@ file:
- `schemuploader.upload`: Permission to use the schem file upload feature
- `schemuploader.download`: Permission to use the schem file download feature
+
+## About Statistics Data
+
+BungeePteroPower collects anonymous statistical data using [bStats](https://bstats.org/).
+You can find the statistics data [here](https://bstats.org/plugin/bukkit/SchemUploader/21061).
+
+bStats is used to understand the usage of the plugin and help improve it.
+To disable the collection of statistical data, please set `enabled` to `false` in `plugins/bStats/config.yml`
diff --git a/README_ja.md b/README_ja.md
index fae807b..bb861af 100644
--- a/README_ja.md
+++ b/README_ja.md
@@ -69,3 +69,11 @@ download:
- `schemuploader.upload`: schemファイルのアップロード機能を使用する権限
- `schemuploader.download`: schemファイルのダウンロード機能を使用する権限
+
+## 統計データについて
+
+BungeePteroPowerは、[bStats](https://bstats.org/)を使用して匿名の統計データを収集しています。
+統計データは[こちら](https://bstats.org/plugin/bukkit/SchemUploader/21061)。
+
+bStatsは、プラグインの使用状況を把握するために使用され、プラグインの改善に役立てられます。
+統計データの収集を無効にするには、`plugins/bStats/config.yml`の `enabled` を `false` に設定してください。
diff --git a/pom.xml b/pom.xml
index 567a0e0..27c44f9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -76,5 +76,10 @@
2.8.9
provided
+
+ org.bstats
+ bstats-bukkit
+ 3.0.2
+
diff --git a/src/main/java/com/kamesuta/schemuploader/CommandListener.java b/src/main/java/com/kamesuta/schemuploader/CommandListener.java
index bc8d7d2..38c1ec5 100644
--- a/src/main/java/com/kamesuta/schemuploader/CommandListener.java
+++ b/src/main/java/com/kamesuta/schemuploader/CommandListener.java
@@ -91,6 +91,10 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
// Send an error message if the upload fails
if (!result.success) {
sender.sendMessage(plugin.messages.error("upload_failed", result.error));
+
+ // Add record to statistics
+ plugin.statistics.actionCounter.increment(Statistics.ActionCounter.ActionType.UPLOAD_FAILURE);
+
return;
}
@@ -101,6 +105,9 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, result.url))
.create()
);
+
+ // Add record to statistics
+ plugin.statistics.actionCounter.increment(Statistics.ActionCounter.ActionType.UPLOAD_SUCCESS);
});
return true;
@@ -174,6 +181,10 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
} else {
sender.sendMessage(plugin.messages.error("download_failed", result.error));
}
+
+ // Add record to statistics
+ plugin.statistics.actionCounter.increment(Statistics.ActionCounter.ActionType.DOWNLOAD_FAILURE);
+
return;
}
@@ -184,6 +195,9 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, url))
.create()
);
+
+ // Add record to statistics
+ plugin.statistics.actionCounter.increment(Statistics.ActionCounter.ActionType.DOWNLOAD_SUCCESS);
});
return true;
diff --git a/src/main/java/com/kamesuta/schemuploader/SchemUploader.java b/src/main/java/com/kamesuta/schemuploader/SchemUploader.java
index 6bd2310..9d38821 100644
--- a/src/main/java/com/kamesuta/schemuploader/SchemUploader.java
+++ b/src/main/java/com/kamesuta/schemuploader/SchemUploader.java
@@ -18,6 +18,11 @@ public final class SchemUploader extends JavaPlugin {
*/
public static SchemUploader plugin;
+ /**
+ * Statistics
+ */
+ public Statistics statistics;
+
/**
* Fallback Translations
*/
@@ -68,6 +73,9 @@ public void onEnable() {
// Register commands
CommandListener.register();
+
+ // Statistics
+ statistics = new Statistics();
}
@Override
diff --git a/src/main/java/com/kamesuta/schemuploader/Statistics.java b/src/main/java/com/kamesuta/schemuploader/Statistics.java
new file mode 100644
index 0000000..f9b8e3d
--- /dev/null
+++ b/src/main/java/com/kamesuta/schemuploader/Statistics.java
@@ -0,0 +1,90 @@
+package com.kamesuta.schemuploader;
+
+import org.bstats.bukkit.Metrics;
+import org.bstats.charts.SimplePie;
+import org.bstats.charts.SingleLineChart;
+
+import java.util.EnumMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static com.kamesuta.schemuploader.SchemUploader.plugin;
+
+/**
+ * Statistics of the plugin
+ */
+public class Statistics {
+ public final ActionCounter actionCounter = new ActionCounter();
+
+ /**
+ * Register bStats
+ */
+ public void register() {
+ // Enable bStats
+ Metrics metrics = new Metrics(plugin, 21061);
+
+ // Config charts
+ metrics.addCustomChart(new SimplePie("uploadEnabled", () -> PluginConfig.uploadEnabled ? "enabled" : "disabled"));
+ metrics.addCustomChart(new SimplePie("downloadEnabled", () -> PluginConfig.downloadEnabled ? "enabled" : "disabled"));
+ metrics.addCustomChart(new SimplePie("downloadUrlRestrictionEnabled", () -> PluginConfig.downloadUrlRestrictionEnabled ? "enabled" : "disabled"));
+ metrics.addCustomChart(new SimplePie("language", () -> PluginConfig.language));
+
+ // The number of power actions performed
+ for (ActionCounter.ActionType actionType : ActionCounter.ActionType.values()) {
+ metrics.addCustomChart(new SingleLineChart(actionType.name, () -> actionCounter.collect(actionType)));
+ }
+ }
+
+ /**
+ * The counter for each action
+ */
+ public static class ActionCounter {
+ private final Map countMap = new EnumMap<>(ActionType.class);
+
+ /**
+ * Increment the counter
+ *
+ * @param actionType type of action to get statistics for
+ */
+ public void increment(ActionType actionType) {
+ getOrCreate(actionType).incrementAndGet();
+ }
+
+ /**
+ * Get the collected value and reset the counter
+ *
+ * @param actionType type of action to get statistics for
+ * @return The collected value
+ */
+ public int collect(ActionType actionType) {
+ return getOrCreate(actionType).getAndSet(0);
+ }
+
+ /**
+ * Get or create the counter
+ *
+ * @param actionType type of action to get statistics for
+ * @return The counter
+ */
+ private AtomicInteger getOrCreate(ActionType actionType) {
+ return countMap.computeIfAbsent(actionType, (k) -> new AtomicInteger());
+ }
+
+ /**
+ * The service to collect statistics
+ */
+ public enum ActionType {
+ UPLOAD_SUCCESS("upload_success"),
+ DOWNLOAD_SUCCESS("download_success"),
+ UPLOAD_FAILURE("upload_failure"),
+ DOWNLOAD_FAILURE("download_failure"),
+ ;
+
+ public final String name;
+
+ ActionType(String name) {
+ this.name = name;
+ }
+ }
+ }
+}