summaryrefslogtreecommitdiff
path: root/src/main/java/com/keuin
diff options
context:
space:
mode:
authorKeuin <[email protected]>2020-12-29 15:15:46 +0800
committerKeuin <[email protected]>2020-12-29 15:15:46 +0800
commit0e296b04dc926356a5905bdcd844c0f7cb07100c (patch)
tree6d1a783f32a8ec9474bb51c36e57336c573002df /src/main/java/com/keuin
parentcf2f9b922360e630229e04262c05d8c91da6916d (diff)
1.3.0: add `/blame stat` for showing statistics.
Diffstat (limited to 'src/main/java/com/keuin')
-rw-r--r--src/main/java/com/keuin/blame/Blame.java11
-rw-r--r--src/main/java/com/keuin/blame/command/BlameStatCommand.java109
-rw-r--r--src/main/java/com/keuin/blame/data/helper/VersionedLogEntryHelper.java22
3 files changed, 140 insertions, 2 deletions
diff --git a/src/main/java/com/keuin/blame/Blame.java b/src/main/java/com/keuin/blame/Blame.java
index 2bf93ca..a4c806d 100644
--- a/src/main/java/com/keuin/blame/Blame.java
+++ b/src/main/java/com/keuin/blame/Blame.java
@@ -5,6 +5,7 @@ import com.keuin.blame.adapter.*;
import com.keuin.blame.adapter.handler.PlaceBlockHandler;
import com.keuin.blame.command.BlameBlockCommand;
import com.keuin.blame.command.BlameLimitCommand;
+import com.keuin.blame.command.BlameStatCommand;
import com.keuin.blame.config.BlameConfig;
import com.keuin.blame.lookup.LookupManager;
import com.keuin.blame.util.DatabaseUtil;
@@ -124,11 +125,17 @@ public class Blame implements ModInitializer {
.then(CommandManager.argument("y", IntegerArgumentType.integer())
.then(CommandManager.argument("z", IntegerArgumentType.integer())
.then(CommandManager.argument("world", StringArgumentType.greedyString())
- .executes(BlameBlockCommand::blameGivenBlockPos)))))));
+ .executes(BlameBlockCommand::blameGivenBlockPos))))))
+ );
commandDispatcher.register(
CommandManager.literal("blame").then(CommandManager.literal("limit")
.then(CommandManager.argument("limit", IntegerArgumentType.integer(1, 255))
- .executes(BlameLimitCommand::setLimit))));
+ .executes(BlameLimitCommand::setLimit)))
+ );
+ commandDispatcher.register(
+ CommandManager.literal("blame").then(CommandManager.literal("stat")
+ .executes(BlameStatCommand::showStat))
+ );
}
});
}
diff --git a/src/main/java/com/keuin/blame/command/BlameStatCommand.java b/src/main/java/com/keuin/blame/command/BlameStatCommand.java
new file mode 100644
index 0000000..677ea88
--- /dev/null
+++ b/src/main/java/com/keuin/blame/command/BlameStatCommand.java
@@ -0,0 +1,109 @@
+package com.keuin.blame.command;
+
+import com.keuin.blame.data.entry.LogEntry;
+import com.keuin.blame.data.helper.VersionedLogEntryHelper;
+import com.keuin.blame.util.DatabaseUtil;
+import com.keuin.blame.util.PrintUtil;
+import com.mojang.brigadier.context.CommandContext;
+import com.mongodb.MongoClientException;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoDatabase;
+import net.minecraft.server.command.ServerCommandSource;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+import java.util.logging.Logger;
+
+public class BlameStatCommand {
+
+ private static final Logger logger = Logger.getLogger(BlameStatCommand.class.getName());
+
+ public static int showStat(CommandContext<ServerCommandSource> context) {
+ showStat(new ShowStatCallback() {
+ @Override
+ public void showStat(@Nullable BlameStat stat) {
+ StringBuilder sb = new StringBuilder();
+ if (stat != null) {
+ sb.append("Data statistics\n");
+ sb.append("===============\n");
+ sb.append("\n");
+ sb.append("# Count by subjects\n");
+ stat.getCountMap().forEach((subjectId, count) -> {
+ sb.append(subjectId).append(": ").append(count).append("\n");
+ });
+ sb.append("\n");
+ sb.append("=== END ===\n");
+ } else {
+ sb.append("Failed to get statistics. Please refer to server log for more information.\n");
+ }
+ PrintUtil.msgInfo(context, sb.toString());
+ }
+ });
+ return Commands.SUCCESS;
+ }
+
+ public static void showStat(ShowStatCallback callback) {
+ Objects.requireNonNull(callback);
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ logger.info("Collecting statistics...");
+ try (final MongoClient mongoClient = MongoClients.create(DatabaseUtil.CLIENT_SETTINGS)) {
+ final MongoDatabase db = mongoClient.getDatabase(
+ DatabaseUtil.MONGO_CONFIG.getDatabaseName()
+ );
+ final MongoCollection<LogEntry> collection = db.getCollection(
+ DatabaseUtil.MONGO_CONFIG.getLogCollectionName(), LogEntry.class
+ );
+ Collection<String> ids = VersionedLogEntryHelper.getLoggedSubjectsId(collection);
+
+ // count by distinct subjects
+ Map<String, Long> countMap = new HashMap<>();
+ for (String subjectId : ids) {
+ long count = VersionedLogEntryHelper.countBySubjectId(collection, subjectId);
+ countMap.put(subjectId, count);
+ }
+
+ // invoke callback
+ callback.showStat(new BlameStat(countMap));
+ } catch (MongoClientException exception) {
+ logger.severe("Failed when querying the database: " + exception +
+ ". Failed to get statistics.");
+ callback.showStat(null);
+ }
+ }
+ }).start();
+ }
+
+ public static class BlameStat {
+ private final Map<String, Long> countMap;
+
+ public BlameStat(Map<String, Long> countMap) {
+ this.countMap = countMap;
+ }
+
+ public Map<String, Long> getCountMap() {
+ return Collections.unmodifiableMap(countMap);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ BlameStat blameStat = (BlameStat) o;
+ return Objects.equals(countMap, blameStat.countMap);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(countMap);
+ }
+ }
+
+ public interface ShowStatCallback {
+ void showStat(@Nullable BlameStat stat);
+ }
+
+}
diff --git a/src/main/java/com/keuin/blame/data/helper/VersionedLogEntryHelper.java b/src/main/java/com/keuin/blame/data/helper/VersionedLogEntryHelper.java
new file mode 100644
index 0000000..064ae87
--- /dev/null
+++ b/src/main/java/com/keuin/blame/data/helper/VersionedLogEntryHelper.java
@@ -0,0 +1,22 @@
+package com.keuin.blame.data.helper;
+
+import com.keuin.blame.data.entry.LogEntry;
+import com.keuin.blame.data.entry.LogEntryNames;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.model.Filters;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class VersionedLogEntryHelper {
+ public static Collection<String> getLoggedSubjectsId(MongoCollection<LogEntry> collection) {
+ List<String> list = new ArrayList<>();
+ for (String s : collection.distinct(LogEntryNames.SUBJECT_ID, String.class))
+ list.add(s);
+ return list;
+ }
+ public static long countBySubjectId(MongoCollection<LogEntry> collection, String subjectId) {
+ return collection.countDocuments(Filters.eq(LogEntryNames.SUBJECT_ID, subjectId));
+ }
+}