From d1c0488a9f782c0b5d8bfb4c60f4ae3b0e3440e5 Mon Sep 17 00:00:00 2001 From: Keuin Date: Fri, 25 Dec 2020 16:25:30 +0800 Subject: Add `/blame limit ` command to change the lookup limit. Improve the implementation of look up limit. --- src/main/java/com/keuin/blame/Blame.java | 29 +++++------ .../com/keuin/blame/command/BlameBlockCommand.java | 22 ++++----- .../com/keuin/blame/command/BlameLimitCommand.java | 56 ++++++++++++++++++++++ .../java/com/keuin/blame/command/Commands.java | 6 +++ .../blame/lookup/LookupFilterWithCallback.java | 16 +++++-- .../java/com/keuin/blame/lookup/LookupManager.java | 6 ++- .../java/com/keuin/blame/lookup/LookupWorker.java | 2 +- .../java/com/keuin/blame/test/TestDatabase.java | 2 +- 8 files changed, 101 insertions(+), 38 deletions(-) create mode 100644 src/main/java/com/keuin/blame/command/BlameLimitCommand.java create mode 100644 src/main/java/com/keuin/blame/command/Commands.java diff --git a/src/main/java/com/keuin/blame/Blame.java b/src/main/java/com/keuin/blame/Blame.java index b09f23d..ab22590 100644 --- a/src/main/java/com/keuin/blame/Blame.java +++ b/src/main/java/com/keuin/blame/Blame.java @@ -4,6 +4,7 @@ import com.google.gson.Gson; 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.config.BlameConfig; import com.keuin.blame.lookup.LookupManager; import com.keuin.blame.util.PrintUtil; @@ -96,24 +97,16 @@ public class Blame implements ModInitializer { @Override public void register(CommandDispatcher commandDispatcher, boolean b) { commandDispatcher.register( - CommandManager.literal("blame") - .then( - CommandManager.literal("block") - .then( - CommandManager.argument("x", IntegerArgumentType.integer()) - .then( - CommandManager.argument("y", IntegerArgumentType.integer()) - .then( - CommandManager.argument("z", IntegerArgumentType.integer()) - .then( - CommandManager.argument("world", StringArgumentType.greedyString()) - .executes(BlameBlockCommand::run) - ) - ) - ) - ) - ) - ); + CommandManager.literal("blame").then(CommandManager.literal("block") + .then(CommandManager.argument("x", IntegerArgumentType.integer()) + .then(CommandManager.argument("y", IntegerArgumentType.integer()) + .then(CommandManager.argument("z", IntegerArgumentType.integer()) + .then(CommandManager.argument("world", StringArgumentType.greedyString()) + .executes(BlameBlockCommand::blameBlock))))))); + commandDispatcher.register( + CommandManager.literal("blame").then(CommandManager.literal("limit") + .then(CommandManager.argument("limit", IntegerArgumentType.integer(1, 255)) + .executes(BlameLimitCommand::setLimit)))); } }); } diff --git a/src/main/java/com/keuin/blame/command/BlameBlockCommand.java b/src/main/java/com/keuin/blame/command/BlameBlockCommand.java index 7d85e77..578870d 100644 --- a/src/main/java/com/keuin/blame/command/BlameBlockCommand.java +++ b/src/main/java/com/keuin/blame/command/BlameBlockCommand.java @@ -11,14 +11,13 @@ import net.minecraft.entity.Entity; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; -import java.util.Iterator; +import static com.keuin.blame.command.Commands.FAILED; +import static com.keuin.blame.command.Commands.SUCCESS; public class BlameBlockCommand { - private static final int SUCCESS = 1; - private static final int FAILED = -1; - public static int run(CommandContext context) { + public static int blameBlock(CommandContext context) { Entity entity = context.getSource().getEntity(); if (!(entity instanceof ServerPlayerEntity)) { // can only be executed by player @@ -34,7 +33,8 @@ public class BlameBlockCommand { WorldPos blockPos = new WorldPos(world, x, y, z); LookupManager.INSTANCE.lookup( new BlockPosLookupFilter(blockPos), - new Callback(context) + new Callback(context), + BlameLimitCommand.getLookupLimit(playerEntity.getUuid()) ); return SUCCESS; } @@ -50,18 +50,16 @@ public class BlameBlockCommand { @Override public void onLookupFinishes(Iterable logEntries) { StringBuilder printBuilder = new StringBuilder(); - Iterator iterator = logEntries.iterator(); - int printCount; - for (printCount = 0; printCount < 5; ++printCount) { - if (!iterator.hasNext()) - break; - LogEntry logEntry = iterator.next(); + int printCount = 0; + for (LogEntry logEntry : logEntries) { printBuilder.append(logEntry.toString()); printBuilder.append("\n") .append("================") .append("\n"); + ++printCount; } - printBuilder.append(String.format("Displayed the most recent %d items.", printCount)); + printBuilder.append(String.format("Displayed the most recent %d items. " + + "Use `/blame limit` to change your display limit.", printCount)); PrintUtil.msgInfo(context, printBuilder.toString()); } } diff --git a/src/main/java/com/keuin/blame/command/BlameLimitCommand.java b/src/main/java/com/keuin/blame/command/BlameLimitCommand.java new file mode 100644 index 0000000..a31a2f9 --- /dev/null +++ b/src/main/java/com/keuin/blame/command/BlameLimitCommand.java @@ -0,0 +1,56 @@ +package com.keuin.blame.command; + +import com.keuin.blame.util.PrintUtil; +import com.mojang.brigadier.context.CommandContext; +import net.minecraft.entity.Entity; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.server.network.ServerPlayerEntity; + +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import static com.keuin.blame.command.Commands.FAILED; +import static com.keuin.blame.command.Commands.SUCCESS; + +public class BlameLimitCommand { + + private static final Map maxLookupCount = new ConcurrentHashMap<>(); + private static final int DEFAULT_LOOKUP_LIMIT = 5; + + public static int setLimit(CommandContext context) { + Entity entity = context.getSource().getEntity(); + if (!(entity instanceof ServerPlayerEntity)) { + // can only be executed by player + return FAILED; + } + ServerPlayerEntity playerEntity = (ServerPlayerEntity) entity; + int newLimit = context.getArgument("limit", Integer.class); + int previousLimit = setLookupLimit(playerEntity.getUuid(), newLimit); + PrintUtil.msgInfo(context, String.format("Set your lookup limit to %d (%d previously).", newLimit, previousLimit)); + return SUCCESS; + } + + /** + * Set one player's lookup limit. + * + * @param playerUUID the player's uuid. + * @param newLookupLimit the new limit. Must be positive. + * @return the previous (or default if not set) limit. + */ + private static int setLookupLimit(UUID playerUUID, int newLookupLimit) { + return Optional.ofNullable(maxLookupCount.put(playerUUID, newLookupLimit)).orElse(DEFAULT_LOOKUP_LIMIT); + } + + /** + * Get one player's lookup limit. + * + * @param playerUUID the player's uuid. + * @return the limit. + */ + public static int getLookupLimit(UUID playerUUID) { + return maxLookupCount.getOrDefault(playerUUID, DEFAULT_LOOKUP_LIMIT); + } + +} diff --git a/src/main/java/com/keuin/blame/command/Commands.java b/src/main/java/com/keuin/blame/command/Commands.java new file mode 100644 index 0000000..8d15ccc --- /dev/null +++ b/src/main/java/com/keuin/blame/command/Commands.java @@ -0,0 +1,6 @@ +package com.keuin.blame.command; + +public class Commands { + public static final int SUCCESS = 1; + public static final int FAILED = -1; +} diff --git a/src/main/java/com/keuin/blame/lookup/LookupFilterWithCallback.java b/src/main/java/com/keuin/blame/lookup/LookupFilterWithCallback.java index cd6743c..f2b07cb 100644 --- a/src/main/java/com/keuin/blame/lookup/LookupFilterWithCallback.java +++ b/src/main/java/com/keuin/blame/lookup/LookupFilterWithCallback.java @@ -6,14 +6,18 @@ class LookupFilterWithCallback { private final LookupCallback callback; private final AbstractLookupFilter filter; + private final int limit; - LookupFilterWithCallback(LookupCallback callback, AbstractLookupFilter filter) { + LookupFilterWithCallback(LookupCallback callback, AbstractLookupFilter filter, int limit) { if (callback == null) throw new IllegalArgumentException("callback cannot be null"); if (filter == null) throw new IllegalArgumentException("filter cannot be null"); + if (limit <= 0) + throw new IllegalArgumentException("limit must be positive"); this.callback = callback; this.filter = filter; + this.limit = limit; } public LookupCallback getCallback() { @@ -24,18 +28,22 @@ class LookupFilterWithCallback { return filter; } + public int getLimit() { + return limit; + } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; LookupFilterWithCallback that = (LookupFilterWithCallback) o; - return callback.equals(that.callback) && + return limit == that.limit && + callback.equals(that.callback) && filter.equals(that.filter); } @Override public int hashCode() { - return Objects.hash(callback, filter); + return Objects.hash(callback, filter, limit); } - } diff --git a/src/main/java/com/keuin/blame/lookup/LookupManager.java b/src/main/java/com/keuin/blame/lookup/LookupManager.java index 2ffa86b..5574dc5 100644 --- a/src/main/java/com/keuin/blame/lookup/LookupManager.java +++ b/src/main/java/com/keuin/blame/lookup/LookupManager.java @@ -25,8 +25,10 @@ public class LookupManager { workers.forEach(LookupWorker::disable); } - public void lookup(AbstractLookupFilter filter, LookupCallback callback) { - queue.add(new LookupFilterWithCallback(callback, filter)); + public void lookup(AbstractLookupFilter filter, LookupCallback callback, int lookUpLimit) { + if (lookUpLimit <= 0) + throw new IllegalArgumentException("lookup limit must be positive"); + queue.add(new LookupFilterWithCallback(callback, filter, lookUpLimit)); } } diff --git a/src/main/java/com/keuin/blame/lookup/LookupWorker.java b/src/main/java/com/keuin/blame/lookup/LookupWorker.java index 1442615..e353e99 100644 --- a/src/main/java/com/keuin/blame/lookup/LookupWorker.java +++ b/src/main/java/com/keuin/blame/lookup/LookupWorker.java @@ -43,7 +43,7 @@ public class LookupWorker extends Thread { time = System.currentTimeMillis(); FindIterable find = filter.find( - collection.find().sort(Sorts.descending("timestamp_millis")) + collection.find().sort(Sorts.descending("timestamp_millis")).limit(item.getLimit()) ); // FindIterable find = collection.find();//.sort(Sorts.descending("timestamp_millis")); time = System.currentTimeMillis() - time; diff --git a/src/main/java/com/keuin/blame/test/TestDatabase.java b/src/main/java/com/keuin/blame/test/TestDatabase.java index 140ca77..84bf4bc 100644 --- a/src/main/java/com/keuin/blame/test/TestDatabase.java +++ b/src/main/java/com/keuin/blame/test/TestDatabase.java @@ -78,7 +78,7 @@ public class TestDatabase { success[0] |= Objects.equals(e, entry); } } - }); + }, 100); Thread.sleep(2000); assertTrue(success[0]); } catch (Exception e) { -- cgit v1.2.3