summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeuin <[email protected]>2021-06-05 10:13:16 +0800
committerKeuin <[email protected]>2021-06-05 10:13:38 +0800
commitbd3427908635c7badc60bfb6ee9dd9c425736b8d (patch)
tree00f0462c4357c2a8e38a5bc0fdfd0b9b5e565907
parenta129cec606c8cfd16cfe407581d8df72baeef1e5 (diff)
allow specifying query amount limit in `/blame block` command; pretty-print in `/blame stat`; update PrintUtil
-rw-r--r--gradle.properties2
-rw-r--r--src/main/java/com/keuin/blame/Blame.java27
-rw-r--r--src/main/java/com/keuin/blame/command/BlameBlockCommand.java37
-rw-r--r--src/main/java/com/keuin/blame/command/BlameLimitCommand.java3
-rw-r--r--src/main/java/com/keuin/blame/command/BlameStatCommand.java36
-rw-r--r--src/main/java/com/keuin/blame/util/PrintUtil.java32
6 files changed, 90 insertions, 47 deletions
diff --git a/gradle.properties b/gradle.properties
index ff9a422..ce22ba0 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,7 +6,7 @@ minecraft_version=1.16.5
yarn_mappings=1.16.5+build.9
loader_version=0.11.3
# Mod Properties
-mod_version=1.3.2-alpha
+mod_version=1.4.0
maven_group=com.keuin.blame
archives_base_name=blame-fabric
# Dependencies
diff --git a/src/main/java/com/keuin/blame/Blame.java b/src/main/java/com/keuin/blame/Blame.java
index 389c14c..ead8dce 100644
--- a/src/main/java/com/keuin/blame/Blame.java
+++ b/src/main/java/com/keuin/blame/Blame.java
@@ -13,6 +13,7 @@ import com.keuin.blame.util.PrintUtil;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.LongArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
@@ -21,12 +22,14 @@ import net.minecraft.command.CommandSource;
import net.minecraft.command.argument.BlockPosArgumentType;
import net.minecraft.command.argument.DimensionArgumentType;
import net.minecraft.server.command.CommandManager;
+import net.minecraft.server.command.ServerCommandSource;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.util.Arrays;
import java.util.logging.Logger;
public class Blame implements ModInitializer {
@@ -89,19 +92,29 @@ public class Blame implements ModInitializer {
// register
CommandRegistrationCallback.EVENT.register((commandDispatcher, b) -> {
+ final LiteralArgumentBuilder<ServerCommandSource> amountLimitArgument = CommandManager.literal("limit")
+ .then(CommandManager.argument("amount", IntegerArgumentType.integer())
+ .suggests((ctx, builder) -> CommandSource.suggestMatching(Arrays.asList("1", "5", "10"), builder))
+ .executes(BlameBlockCommand::blameGivenBlockPos)
+ ).executes(BlameBlockCommand::blameGivenBlockPos);
+ final LiteralArgumentBuilder<ServerCommandSource> timeRangeArgument = CommandManager.literal("last")
+ .then(CommandManager.argument("time_range", LongArgumentType.longArg())
+ .executes(BlameBlockCommand::blameGivenBlockPos)
+ .then(CommandManager.argument("time_unit", StringArgumentType.word())
+ .suggests((ctx, builder) -> CommandSource.suggestMatching(BlameBlockCommand.timeUnits, builder))
+ .executes(BlameBlockCommand::blameGivenBlockPos)
+ .then(amountLimitArgument)
+ )
+
+ );
commandDispatcher.register(
CommandManager.literal("blame").then(CommandManager.literal("block")
.then(CommandManager.argument("pos", BlockPosArgumentType.blockPos())
.executes(BlameBlockCommand::blameGivenBlockPos)
.then(CommandManager.argument("world", DimensionArgumentType.dimension())
.executes(BlameBlockCommand::blameGivenBlockPos)
- .then(CommandManager.literal("last")
- .then(CommandManager.argument("time_range", LongArgumentType.longArg())
- .executes(BlameBlockCommand::blameGivenBlockPos)
- .then(CommandManager.argument("time_unit", StringArgumentType.word())
- .suggests((ctx, builder) -> CommandSource.suggestMatching(BlameBlockCommand.timeUnits, builder))
- .executes(BlameBlockCommand::blameGivenBlockPos))
- ))
+ .then(timeRangeArgument)
+ .then(amountLimitArgument)
)))
);
commandDispatcher.register(
diff --git a/src/main/java/com/keuin/blame/command/BlameBlockCommand.java b/src/main/java/com/keuin/blame/command/BlameBlockCommand.java
index eb1888d..eb82fd5 100644
--- a/src/main/java/com/keuin/blame/command/BlameBlockCommand.java
+++ b/src/main/java/com/keuin/blame/command/BlameBlockCommand.java
@@ -6,6 +6,7 @@ import com.keuin.blame.lookup.*;
import com.keuin.blame.util.MinecraftUtil;
import com.keuin.blame.util.PrettyUtil;
import com.keuin.blame.util.PrintUtil;
+import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.LongArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
@@ -44,6 +45,7 @@ public class BlameBlockCommand {
Entity entity = context.getSource().getEntity();
if (!(entity instanceof ServerPlayerEntity)) {
// can only be executed by player
+ PrintUtil.error(context, "This command cannot be used in server console.");
return FAILED;
}
@@ -63,8 +65,10 @@ public class BlameBlockCommand {
long timeRange;
try {
timeRange = LongArgumentType.getLong(context, "time_range");
- if (timeRange < 0)
+ if (timeRange < 0) {
+ PrintUtil.error(context, "Time range must be positive.");
return FAILED;
+ }
} catch (IllegalArgumentException e) {
timeRange = -1;
}
@@ -73,8 +77,10 @@ public class BlameBlockCommand {
try {
final String timeUnit = StringArgumentType.getString(context, "time_unit");
amplifier = timeUnitAmplifierMap.getOrDefault(timeUnit, -1);
- if (amplifier < 0)
+ if (amplifier < 0) {
+ PrintUtil.error(context, "Invalid time unit.");
return FAILED;
+ }
} catch (IllegalArgumentException e) {
amplifier = 1;
}
@@ -85,6 +91,17 @@ public class BlameBlockCommand {
return FAILED;
}
+ int amountLimit;
+ try {
+ amountLimit = IntegerArgumentType.getInteger(context, "amount");
+ if (amountLimit <= 0) {
+ PrintUtil.error(context, "Amount must be positive.");
+ return FAILED;
+ }
+ } catch (IllegalArgumentException e) {
+ amountLimit = BlameLimitCommand.DEFAULT_LOOKUP_LIMIT;
+ }
+
// String world = MinecraftUtil.worldToString(playerEntity.world);
WorldPos blockPos = new WorldPos(world, x, y, z);
AbstractLookupFilter filter;
@@ -97,7 +114,7 @@ public class BlameBlockCommand {
LookupManager.INSTANCE.lookup(
filter,
new Callback(context),
- BlameLimitCommand.getLookupLimit(playerEntity.getUuid())
+ amountLimit
);
return SUCCESS;
@@ -123,13 +140,13 @@ public class BlameBlockCommand {
boolean isFirst = true;
for (LogEntry logEntry : logEntries) {
if (!isFirst)
- printer.append("\n");
- printer.append(Formatting.YELLOW, "Time: ", PrettyUtil.timestampToString(logEntry.timeMillis), "\n")
- .append(Formatting.YELLOW, "Subject: ", Formatting.AQUA, logEntry.subjectId, "{", logEntry.subjectUUID, "} @ ", logEntry.subjectPos, "\n")
- .append(Formatting.YELLOW, "Action: ", Formatting.AQUA, logEntry.actionType, "\n")
- .append(Formatting.YELLOW, "Object: ", Formatting.AQUA, logEntry.objectType, "[", logEntry.objectId, "] @ ", logEntry.objectPos, "\n")
- .append(Formatting.YELLOW, "Log version: ", logEntry.version, "\n")
- .append(Formatting.YELLOW, "Game version: ", logEntry.gameVersion, "\n")
+ printer.newline();
+ printer.append(Formatting.YELLOW, "Time: ", PrettyUtil.timestampToString(logEntry.timeMillis)).newline()
+ .append(Formatting.YELLOW, "Subject: ", Formatting.AQUA, logEntry.subjectId, "{", logEntry.subjectUUID, "} @ ", logEntry.subjectPos).newline()
+ .append(Formatting.YELLOW, "Action: ", Formatting.AQUA, logEntry.actionType).newline()
+ .append(Formatting.YELLOW, "Object: ", Formatting.AQUA, logEntry.objectType, "[", logEntry.objectId, "] @ ", logEntry.objectPos).newline()
+ .append(Formatting.YELLOW, "Log version: ", logEntry.version).newline()
+ .append(Formatting.YELLOW, "Game version: ", logEntry.gameVersion).newline()
.append("================");
++printCount;
isFirst = false;
diff --git a/src/main/java/com/keuin/blame/command/BlameLimitCommand.java b/src/main/java/com/keuin/blame/command/BlameLimitCommand.java
index a31a2f9..c79d245 100644
--- a/src/main/java/com/keuin/blame/command/BlameLimitCommand.java
+++ b/src/main/java/com/keuin/blame/command/BlameLimitCommand.java
@@ -17,7 +17,7 @@ import static com.keuin.blame.command.Commands.SUCCESS;
public class BlameLimitCommand {
private static final Map<UUID, Integer> maxLookupCount = new ConcurrentHashMap<>();
- private static final int DEFAULT_LOOKUP_LIMIT = 5;
+ public static final int DEFAULT_LOOKUP_LIMIT = 5;
public static int setLimit(CommandContext<ServerCommandSource> context) {
Entity entity = context.getSource().getEntity();
@@ -49,6 +49,7 @@ public class BlameLimitCommand {
* @param playerUUID the player's uuid.
* @return the limit.
*/
+ @Deprecated
public static int getLookupLimit(UUID playerUUID) {
return maxLookupCount.getOrDefault(playerUUID, DEFAULT_LOOKUP_LIMIT);
}
diff --git a/src/main/java/com/keuin/blame/command/BlameStatCommand.java b/src/main/java/com/keuin/blame/command/BlameStatCommand.java
index fade0a1..c42fa8f 100644
--- a/src/main/java/com/keuin/blame/command/BlameStatCommand.java
+++ b/src/main/java/com/keuin/blame/command/BlameStatCommand.java
@@ -12,6 +12,7 @@ import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import net.minecraft.server.command.ServerCommandSource;
+import net.minecraft.util.Formatting;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -22,26 +23,25 @@ public class BlameStatCommand {
private static final Logger logger = Logger.getLogger(BlameStatCommand.class.getName());
public static int showStat(CommandContext<ServerCommandSource> context) {
- PrintUtil.msgInfo(context, "Collecting statistics. This may take a few seconds...");
- showStat(new ShowStatCallback() {
- @Override
- public void showStat(@Nullable BlameStat stat) {
- StringBuilder sb = new StringBuilder();
- if (stat != null) {
- sb.append("Statistics\n");
- sb.append("====\n");
- sb.append("# Count by subjects\n");
- stat.getCountMap().forEach((subjectId, count) -> {
- sb.append("<").append(
- Optional.ofNullable(Strings.emptyToNull(subjectId)).orElse("null")
- ).append(">: ").append(count).append("\n");
- });
- sb.append("=== END ===");
- } else {
- sb.append("Failed to get statistics. Please refer to server log for more information.");
+ PrintUtil.message(context, Formatting.ITALIC, "Collecting statistics. This may take a few seconds...");
+ showStat(stat -> {
+ PrintUtil.Printer sb = PrintUtil.newPrinter();
+ if (stat != null) {
+ sb.append("Logs grouped by subjects:").newline();
+ boolean isFirst = true;
+ for (Map.Entry<String, Long> entry : stat.getCountMap().entrySet()) {
+ if (!isFirst)
+ sb.newline();
+ isFirst = false;
+ final String subjectId = entry.getKey();
+ final long count = entry.getValue();
+ sb.append(Formatting.YELLOW, Optional.ofNullable(Strings.emptyToNull(subjectId)).orElse("null"))
+ .append(": ").append(count);
}
- PrintUtil.msgInfo(context, sb.toString());
+ } else {
+ sb.append(Formatting.RED, "Failed to get statistics. Please refer to server log for more information.");
}
+ sb.sendTo(context);
});
return Commands.SUCCESS;
}
diff --git a/src/main/java/com/keuin/blame/util/PrintUtil.java b/src/main/java/com/keuin/blame/util/PrintUtil.java
index f1d8695..d869a8b 100644
--- a/src/main/java/com/keuin/blame/util/PrintUtil.java
+++ b/src/main/java/com/keuin/blame/util/PrintUtil.java
@@ -1,13 +1,15 @@
package com.keuin.blame.util;
import com.mojang.brigadier.context.CommandContext;
-import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.minecraft.network.MessageType;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.command.ServerCommandSource;
-import net.minecraft.text.*;
+import net.minecraft.text.BaseText;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Style;
+import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -139,16 +141,23 @@ public final class PrintUtil implements ServerLifecycleEvents.ServerStarted {
}
public static void message(CommandContext<ServerCommandSource> context, Object... objects) {
- new Printer().append(objects).sendTo(context);
+ new Printer(false).append(objects).sendTo(context);
+ }
+
+ public static void error(CommandContext<ServerCommandSource> context, Object... objects) {
+ new Printer(true).append(objects).sendTo(context);
}
public static Printer newPrinter() {
- return new Printer();
+ return new Printer(false);
}
public static class Printer {
private final BaseText message = new LiteralText("");
- public Printer() {
+ private final boolean error;
+
+ public Printer(boolean error) {
+ this.error = error;
}
public Printer append(Object... objects) {
@@ -171,16 +180,19 @@ public final class PrintUtil implements ServerLifecycleEvents.ServerStarted {
return this;
}
+ public Printer newline() {
+ return this.append("\n");
+ }
+
public void sendTo(Consumer<Text> receiver) {
receiver.accept(message);
}
public void sendTo(CommandContext<ServerCommandSource> context) {
- try {
- context.getSource().getPlayer().sendSystemMessage(message, UUID_NULL);
- } catch (CommandSyntaxException e) {
- throw new IllegalArgumentException("CommandContext must be of a player");
- }
+ if (error)
+ context.getSource().sendError(message);
+ else
+ context.getSource().sendFeedback(message, false);
}
}