From c4801757a2fda147e1cee65f70f80fb215047525 Mon Sep 17 00:00:00 2001 From: Dico Karssiens Date: Sun, 30 Sep 2018 17:05:42 +0100 Subject: Some changes --- .../dico/dicore/command/ChildCommandAddress.java | 16 +- .../main/java/io/dico/dicore/command/Command.java | 48 +--- .../io/dico/dicore/command/CommandBuilder.java | 11 +- .../java/io/dico/dicore/command/CommandResult.java | 23 -- .../io/dico/dicore/command/ExecutionContext.java | 243 +++++++++++---------- .../io/dico/dicore/command/ExtendedCommand.java | 3 +- .../io/dico/dicore/command/ICommandAddress.java | 33 ++- .../io/dico/dicore/command/ICommandReceiver.java | 22 -- .../dicore/command/ModifiableCommandAddress.java | 17 +- .../dicore/command/PermissionContextFilter.java | 27 +++ .../io/dico/dicore/command/RootCommandAddress.java | 37 +++- .../dicore/command/annotation/PreprocessArgs.java | 1 + .../chat/help/defaults/DefaultPageBuilder.java | 3 +- .../chat/help/insertion/HelpComponentInserter.java | 2 +- .../dicore/command/parameter/ArgumentBuffer.java | 71 +++--- .../parameter/ArgumentMergingPreProcessor.java | 43 ++-- .../dicore/command/parameter/ContextParser.java | 32 +-- .../command/parameter/IArgumentPreProcessor.java | 20 +- .../dicore/command/parameter/ParameterList.java | 16 +- .../command/parameter/type/EnumParameterType.java | 6 +- .../command/parameter/type/ParameterType.java | 52 ----- .../dicore/command/predef/DefaultGroupCommand.java | 4 +- .../registration/reflect/ICommandInterceptor.java | 36 +++ .../registration/reflect/ICommandReceiver.java | 5 + .../registration/reflect/ReflectiveCommand.java | 30 ++- .../reflect/ReflectiveRegistration.java | 42 ++-- .../reflect/KotlinReflectiveRegistration.kt | 16 +- .../example/ParameterInfoObjectExample.java | 73 +++++++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54413 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 172 +++++++++++++++ gradlew.bat | 84 +++++++ .../parcels2/command/AbstractParcelCommands.kt | 16 +- .../dico/parcels2/command/ParcelCommandBuilder.kt | 5 +- .../parcels2/command/ParcelCommandReceivers.kt | 2 +- .../dico/parcels2/command/ParcelParameterTypes.kt | 4 +- .../io/dico/parcels2/command/ParcelTarget.kt | 2 +- .../parcels2/defaultimpl/DefaultParcelGenerator.kt | 1 - .../parcels2/defaultimpl/ParcelProviderImpl.kt | 11 +- .../io/dico/parcels2/listener/ParcelListeners.kt | 2 - src/main/kotlin/io/dico/parcels2/storage/Hikari.kt | 2 +- 41 files changed, 835 insertions(+), 403 deletions(-) delete mode 100644 dicore3/command/src/main/java/io/dico/dicore/command/CommandResult.java delete mode 100644 dicore3/command/src/main/java/io/dico/dicore/command/ICommandReceiver.java create mode 100644 dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ICommandInterceptor.java create mode 100644 dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ICommandReceiver.java create mode 100644 dicore3/command/src/test/java/io/dico/dicore/command/example/ParameterInfoObjectExample.java create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/ChildCommandAddress.java b/dicore3/command/src/main/java/io/dico/dicore/command/ChildCommandAddress.java index 022904e..9a26f61 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/ChildCommandAddress.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/ChildCommandAddress.java @@ -10,6 +10,7 @@ public class ChildCommandAddress extends ModifiableCommandAddress { final List namesModifiable = new ArrayList<>(4); List names = namesModifiable; Command command; + boolean isCommandTrailing; public ChildCommandAddress() { } @@ -89,7 +90,7 @@ public class ChildCommandAddress extends ModifiableCommandAddress { } public void finalizeNames() { - if (names instanceof ArrayList) { + if (names == namesModifiable) { names = Collections.unmodifiableList(namesModifiable); } } @@ -103,4 +104,17 @@ public class ChildCommandAddress extends ModifiableCommandAddress { this.parent = parent; } + @Override + public boolean isCommandTrailing() { + return isCommandTrailing; + } + + @Override + public void setCommandTrailing(boolean trailing) { + if (hasChildren()) { + throw new IllegalStateException("Address already has children, this property can't be modified"); + } + isCommandTrailing = trailing; + } + } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/Command.java b/dicore3/command/src/main/java/io/dico/dicore/command/Command.java index 53e5821..894e74e 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/Command.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/Command.java @@ -70,10 +70,11 @@ public abstract class Command { return this; } + /* public Command preprocessArguments(IArgumentPreProcessor processor) { parameterList.setArgumentPreProcessor(processor); return this; - } + }*/ public final ParameterList getParameterList() { return parameterList; @@ -133,56 +134,23 @@ public abstract class Command { // ---- EXECUTION ---- - public void execute(CommandSender sender, ICommandAddress caller, ArgumentBuffer buffer) { - ExecutionContext executionContext = new ExecutionContext(sender, caller, this, buffer, false); - - try { - executeWithContext(executionContext); - } catch (Throwable t) { - caller.getChatHandler().handleException(sender, executionContext, t); - } - } - - public void executeWithContext(ExecutionContext context) throws CommandException { - //System.out.println("In Command.execute(sender, caller, buffer)#try{"); + public void initializeAndFilterContext(ExecutionContext context) throws CommandException { int i, n; for (i = 0, n = contextFilters.size() - postParameterFilterCount; i < n; i++) { contextFilters.get(i).filterContext(context); } - context.parseParameters(); + context.parse(parameterList); - for (n = contextFilters.size(); i < n; i++) { - contextFilters.get(i).filterContext(context); + if (!context.isTabComplete()) { + for (n = contextFilters.size(); i < n; i++) { + contextFilters.get(i).filterContext(context); + } } - - //System.out.println("Post-contextfilters"); - - String message = execute(context.getSender(), context); - context.sendMessage(EMessageType.RESULT, message); } public abstract String execute(CommandSender sender, ExecutionContext context) throws CommandException; - public List tabComplete(CommandSender sender, ICommandAddress caller, Location location, ArgumentBuffer buffer) { - ExecutionContext executionContext = new ExecutionContext(sender, caller, this, buffer, true); - try { - return tabCompleteWithContext(executionContext, location); - } catch (CommandException ex) { - return Collections.emptyList(); - } - } - - public List tabCompleteWithContext(ExecutionContext context, Location location) throws CommandException { - int i, n; - for (i = 0, n = contextFilters.size() - postParameterFilterCount; i < n; i++) { - contextFilters.get(i).filterContext(context); - } - - context.parseParametersQuietly(); - return tabComplete(context.getSender(), context, location); - } - public List tabComplete(CommandSender sender, ExecutionContext context, Location location) { return context.getSuggestedCompletions(location); } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/CommandBuilder.java b/dicore3/command/src/main/java/io/dico/dicore/command/CommandBuilder.java index 63628d3..e527f27 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/CommandBuilder.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/CommandBuilder.java @@ -265,10 +265,19 @@ public final class CommandBuilder { * @return this * @throws IllegalStateException if the current group has no command */ - public CommandBuilder addRequiredPermission(String permission) { + public CommandBuilder addPermission(String permission) { return addContextFilter(IContextFilter.permission(permission)); } + /** + * Add a required permission to the command of the current group, which can be inherited + * @return this + * @throws IllegalStateException if the current group has no command + */ + public CommandBuilder addInheritablePermission(String permission) { + return addContextFilter(IContextFilter.inheritablePermission(permission)); + } + /** * Jump up a level in the address * diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/CommandResult.java b/dicore3/command/src/main/java/io/dico/dicore/command/CommandResult.java deleted file mode 100644 index 7c4a891..0000000 --- a/dicore3/command/src/main/java/io/dico/dicore/command/CommandResult.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.dico.dicore.command; - -/** - * This enum is intended to provide some constants for default messages. - * Can be returned by a reflective command. - * Currently, no constants have an actual message. - * Prone to removal in the future because of lack of usefullness. - */ -public enum CommandResult { - SUCCESS(null), - QUIET_ERROR(null); - - private final String message; - - CommandResult(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - -} diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/ExecutionContext.java b/dicore3/command/src/main/java/io/dico/dicore/command/ExecutionContext.java index 2a074e1..a329f40 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/ExecutionContext.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/ExecutionContext.java @@ -17,27 +17,32 @@ import java.util.*; * It is also responsible for keeping track of the parameter to complete in the case of a tab completion. */ public class ExecutionContext { - private CommandSender sender; + // Sender of the command + private final CommandSender sender; + // Address while parsing parameters with ContextParser private ICommandAddress address; + // Command to execute private Command command; - private ArgumentBuffer originalBuffer; - private ArgumentBuffer processedBuffer; + // if this flag is set, this execution is only for completion purposes. + private boolean tabComplete; + + private final ArgumentBuffer buffer; + // private ArgumentBuffer processedBuffer; // caches the buffer's cursor before parsing. This is needed to provide the original input of the player. private int cursorStart; // when the context starts parsing parameters, this flag is set, and any subsequent calls to #parseParameters() throw an IllegalStateException. - private boolean attemptedToParse; + //private boolean attemptedToParse; // The parsed parameter values, mapped by parameter name. // This also includes default values. All parameters from the parameter list are present if parsing was successful. - private Map parameterValueMap; + private Map parameterValueMap = new HashMap<>(); // this set contains the names of the parameters that were present in the command, and not given a default value. - private Set parsedParameters; + private Set parsedParameters = new HashSet<>(); + - // if this flag is set, this execution is only for completion purposes. - private boolean tabComplete; // these fields store information required to provide completions. // the parameter to complete is the parameter that threw an exception when it was parsing. // the exception's message was discarded because it is a completion. @@ -48,37 +53,11 @@ public class ExecutionContext { // if this flag is set, any messages sent through the sendMessage methods are discarded. private boolean muted; - public ExecutionContext(CommandSender sender, boolean tabComplete) { + public ExecutionContext(CommandSender sender, ArgumentBuffer buffer, boolean tabComplete) { this.sender = Objects.requireNonNull(sender); + this.buffer = Objects.requireNonNull(buffer); this.muted = tabComplete; this.tabComplete = tabComplete; - } - - /** - * Construct an execution context that is ready to parse the parameter values. - * - * @param sender the sender - * @param address the address - * @param buffer the arguments - * @param tabComplete true if this execution is a tab-completion - */ - public ExecutionContext(CommandSender sender, ICommandAddress address, Command command, ArgumentBuffer buffer, boolean tabComplete) { - this(sender, tabComplete); - targetAcquired(address, command, buffer); - } - - void requireAddressPresent(boolean present) { - //noinspection DoubleNegation - if ((address != null) != present) { - throw new IllegalStateException(); - } - } - - void targetAcquired(ICommandAddress address, Command command, ArgumentBuffer buffer) { - requireAddressPresent(false); - - this.address = Objects.requireNonNull(address); - this.command = Objects.requireNonNull(command); // If its tab completing, keep the empty element that might be at the end of the buffer // due to a space at the end of the command. @@ -86,65 +65,21 @@ public class ExecutionContext { if (!tabComplete) { buffer.dropTrailingEmptyElements(); } - - this.originalBuffer = buffer; - this.processedBuffer = buffer.preprocessArguments(getParameterList().getArgumentPreProcessor()); - this.cursorStart = buffer.getCursor(); } /** - * Parse the parameters. If no exception is thrown, they were parsed successfully, and the command may continue post-parameter execution. + * Construct an execution context that is ready to parse the parameter values. * - * @throws CommandException if an error occurs while parsing the parameters. - */ - synchronized void parseParameters() throws CommandException { - requireAddressPresent(true); - if (attemptedToParse) { - throw new IllegalStateException(); - } - - attemptedToParse = true; - - ContextParser parser = new ContextParser(this); - - parameterValueMap = parser.getValueMap(); - parsedParameters = parser.getParsedKeys(); - - parser.parse(); - } - - - /** - * Attempts to parse parameters, without throwing an exception or sending any message. - * This method is typically used by tab completions. - * After calling this method, the context is ready to provide completions. + * @param sender the sender + * @param address the address + * @param command the command + * @param buffer the arguments + * @param tabComplete true if this execution is a tab-completion */ - synchronized void parseParametersQuietly() { - requireAddressPresent(true); - if (attemptedToParse) { - throw new IllegalStateException(); - } - - attemptedToParse = true; - - boolean before = muted; - muted = true; - try { - ContextParser parser = new ContextParser(this); - - parameterValueMap = parser.getValueMap(); - parsedParameters = parser.getParsedKeys(); - - parser.parse(); - - parameterToComplete = parser.getCompletionTarget(); - parameterToCompleteCursor = parser.getCompletionCursor(); - - } catch (CommandException ignored) { - - } finally { - muted = before; - } + public ExecutionContext(CommandSender sender, ICommandAddress address, Command command, ArgumentBuffer buffer, boolean tabComplete) { + this(sender, buffer, tabComplete); + setAddress(address); + setCommand(command); } /** @@ -156,6 +91,13 @@ public class ExecutionContext { return sender; } + /** + * @return the buffer of arguments + */ + public ArgumentBuffer getBuffer() { + return buffer; + } + /** * Command's address * @@ -165,6 +107,15 @@ public class ExecutionContext { return address; } + /** + * Set the address + * + * @param address the new address + */ + public void setAddress(ICommandAddress address) { + this.address = address; + } + /** * The command * @@ -174,13 +125,60 @@ public class ExecutionContext { return command; } + /** + * Set the command + * + * @param command the new command + */ + public void setCommand(Command command) { + this.command = command; + } + + /** + * @return true if this context is for a tab completion. + */ + public boolean isTabComplete() { + return tabComplete; + } + + /** + * @return true if this context is muted. + */ + public boolean isMuted() { + return muted; + } + + /** + * Parse parameters from the given parameter list, + * adding their values to the cache of this context. + * + * @param parameterList the parameterList + * @throws CommandException if the arguments are not valid + */ + public void parse(ParameterList parameterList) throws CommandException { + cursorStart = buffer.getCursor(); + + ContextParser parser = new ContextParser(this, parameterList, parameterValueMap, parsedParameters); + + try { + parser.parse(); + } finally { + if (tabComplete) { + parameterToComplete = parser.getCompletionTarget(); + parameterToCompleteCursor = parser.getCompletionCursor(); + } + } + + } + /** * The command's parameter definition. * * @return the parameter list */ + @Deprecated public ParameterList getParameterList() { - return command.getParameterList(); + return null;//command.getParameterList(); } /** @@ -188,8 +186,9 @@ public class ExecutionContext { * * @return the original buffer */ + @Deprecated public ArgumentBuffer getOriginalBuffer() { - return originalBuffer; + return buffer; } /** @@ -197,8 +196,9 @@ public class ExecutionContext { * * @return the argument buffer */ + @Deprecated public ArgumentBuffer getProcessedBuffer() { - return processedBuffer; + return buffer; } /** @@ -216,7 +216,7 @@ public class ExecutionContext { * @return original arguments. */ public String[] getOriginal() { - return originalBuffer.getArrayFromIndex(cursorStart); + return buffer.getArrayFromIndex(cursorStart); } /** @@ -225,7 +225,7 @@ public class ExecutionContext { * @return the path used to access this address. */ public String[] getRoute() { - return Arrays.copyOf(originalBuffer.toArray(), address.getDepth()); + return Arrays.copyOf(buffer.toArray(), address.getDepth()); } public Formatting getFormat(EMessageType type) { @@ -238,9 +238,16 @@ public class ExecutionContext { * @return the full command */ public String getRawInput() { - return originalBuffer.getRawInput(); + return buffer.getRawInput(); } + /** + * Get the value of the parameter with the given name + * + * @param name the parameter's name + * @param expected type + * @return the parsed value or the default value + */ @SuppressWarnings("unchecked") public T get(String name) { if (!parameterValueMap.containsKey(name)) { @@ -254,15 +261,23 @@ public class ExecutionContext { } } - @SuppressWarnings("unchecked") - public T get(int index) { - return get(getParameterList().getIndexedParameterName(index)); - } - + /** + * Get the value of the flag with the given name + * + * @param flag the flag's name, without preceding "-" + * @param expected type + * @return the parsed value or the default value + */ public T getFlag(String flag) { return get("-" + flag); } + @SuppressWarnings("unchecked") + @Deprecated + public T get(int index) { + return null;//get(getParameterList().getIndexedParameterName(index)); + } + /** * Checks if the parameter by the name was provided in the command's arguments. * @@ -279,8 +294,9 @@ public class ExecutionContext { * @param index the parameter index * @return true if it was provided */ + @Deprecated public boolean isProvided(int index) { - return isProvided(getParameterList().getIndexedParameterName(index)); + return false;//isProvided(getParameterList().getIndexedParameterName(index)); } /** @@ -293,20 +309,6 @@ public class ExecutionContext { return parameterToComplete; } - /** - * @return true if this context is muted. - */ - public boolean isMuted() { - return muted; - } - - /** - * @return true if this context is for a tab completion. - */ - public boolean isTabComplete() { - return tabComplete; - } - /** * Get suggested completions. * @@ -315,19 +317,22 @@ public class ExecutionContext { */ public List getSuggestedCompletions(Location location) { if (parameterToComplete != null) { - return parameterToComplete.complete(this, location, processedBuffer.getUnaffectingCopy().setCursor(parameterToCompleteCursor)); + return parameterToComplete.complete(this, location, buffer.getUnaffectingCopy().setCursor(parameterToCompleteCursor)); } - ParameterList parameterList = getParameterList(); List result = new ArrayList<>(); for (String name : parameterValueMap.keySet()) { - if (parameterList.getParameterByName(name).isFlag() && !parsedParameters.contains(name)) { + if (name.startsWith("-") && !parsedParameters.contains(name)) { result.add(name); } } return result; } + /* + Chat handling + */ + public void sendMessage(String message) { sendMessage(true, message); } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/ExtendedCommand.java b/dicore3/command/src/main/java/io/dico/dicore/command/ExtendedCommand.java index a34d30d..47c2aca 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/ExtendedCommand.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/ExtendedCommand.java @@ -55,9 +55,10 @@ public abstract class ExtendedCommand> extends Comm return modifiable ? (T) super.setShortDescription(shortDescription) : newModifiableInstance().setShortDescription(shortDescription); } + /* @Override public T preprocessArguments(IArgumentPreProcessor processor) { return modifiable ? (T) super.preprocessArguments(processor) : newModifiableInstance().preprocessArguments(processor); - } + }*/ } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/ICommandAddress.java b/dicore3/command/src/main/java/io/dico/dicore/command/ICommandAddress.java index bef20e4..158b1f0 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/ICommandAddress.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/ICommandAddress.java @@ -2,6 +2,7 @@ package io.dico.dicore.command; import io.dico.dicore.command.chat.IChatHandler; import io.dico.dicore.command.parameter.ArgumentBuffer; +import io.dico.dicore.command.parameter.ParameterList; import io.dico.dicore.command.predef.PredefinedCommand; import org.bukkit.command.CommandSender; @@ -131,6 +132,16 @@ public interface ICommandAddress { * Get an unmodifiable view of the children of this address. * Values might be duplicated for aliases. * + *

+ * To iterate children without duplicates, you can do something like this: + *

{@code
+     *     for (String key : address.getChildrenMainKeys()) {
+     *         ICommandAddress child = address.getChild(key);
+     *         // do stuff with child
+     *     }
+     *     }
+ *

+ * * @return the children of this address. */ Map getChildren(); @@ -144,14 +155,19 @@ public interface ICommandAddress { ICommandAddress getChild(String key); /** - * Query for a child at the given key, with the given context for reference. - * Can be used to override behaviour of the tree. + * Query for a child using the given buffer, with the given context for reference. + * Can be used to override behaviour of the address tree. + *

+ * The default implementation is as follows: + *

{@code
+     * return buffer.hasNext() ? getChild(buffer.next()) : null;
+     * }
* - * @param key the key. The name or alias of a command. * @param context context of a command being executed + * @param buffer the buffer. The name or alias of a command. * @return the child, or null if it's not found, altered freely by the implementation */ - ICommandAddress getChild(String key, ExecutionContext context) throws CommandException; + ICommandAddress getChild(ExecutionContext context, ArgumentBuffer buffer) throws CommandException; /** * Get the command dispatcher for this tree @@ -165,6 +181,15 @@ public interface ICommandAddress { */ IChatHandler getChatHandler(); + /** + * Returns if the command attached to this address should be treated as trailing. + * A trailing command is executed whenever the address is scanned for children. + * Its parameters are parsed and added to the context. + * + * @return true if the command attached to this address should be treated as trailing. + */ + boolean isCommandTrailing(); + static ICommandAddress newChild() { return new ChildCommandAddress(); } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/ICommandReceiver.java b/dicore3/command/src/main/java/io/dico/dicore/command/ICommandReceiver.java deleted file mode 100644 index 6660bf8..0000000 --- a/dicore3/command/src/main/java/io/dico/dicore/command/ICommandReceiver.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.dico.dicore.command; - -import org.bukkit.plugin.Plugin; - -import java.lang.reflect.Method; - -public interface ICommandReceiver { - - interface Factory { - - ICommandReceiver getReceiver(ExecutionContext context, Method target, String cmdName); - - Plugin getPlugin(); - - // type is CoroutineContext, but we avoid referring to Kotlin runtime here - default Object getCoroutineContext() { - return null; - } - - } - -} diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/ModifiableCommandAddress.java b/dicore3/command/src/main/java/io/dico/dicore/command/ModifiableCommandAddress.java index 0c4c476..0cfd755 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/ModifiableCommandAddress.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/ModifiableCommandAddress.java @@ -2,6 +2,8 @@ package io.dico.dicore.command; import io.dico.dicore.command.chat.ChatHandlers; import io.dico.dicore.command.chat.IChatHandler; +import io.dico.dicore.command.parameter.ArgumentBuffer; +import io.dico.dicore.command.parameter.ParameterList; import io.dico.dicore.command.predef.DefaultGroupCommand; import io.dico.dicore.command.predef.HelpCommand; import io.dico.dicore.command.predef.PredefinedCommand; @@ -36,7 +38,7 @@ public abstract class ModifiableCommandAddress implements ICommandAddress { @Override public boolean hasUserDeclaredCommand() { Command command = getCommand(); - return command != null && !(command instanceof PredefinedCommand) && !(command instanceof DefaultGroupCommand); + return command != null && !(command instanceof PredefinedCommand); } @Override @@ -139,8 +141,8 @@ public abstract class ModifiableCommandAddress implements ICommandAddress { } @Override - public ChildCommandAddress getChild(String key, ExecutionContext context) throws CommandException { - return getChild(key); + public ChildCommandAddress getChild(ExecutionContext context, ArgumentBuffer buffer) throws CommandException { + return buffer.hasNext() ? getChild(buffer.next()) : null; } public void addChild(ICommandAddress child) { @@ -264,6 +266,15 @@ public abstract class ModifiableCommandAddress implements ICommandAddress { return getRoot(); } + @Override + public boolean isCommandTrailing() { + return false; + } + + public void setCommandTrailing(boolean trailing) { + throw new UnsupportedOperationException(); + } + void appendDebugInformation(StringBuilder target, String linePrefix, Set seen) { target.append('\n').append(linePrefix); if (!seen.add(this)) { diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/PermissionContextFilter.java b/dicore3/command/src/main/java/io/dico/dicore/command/PermissionContextFilter.java index 3ca1131..75b2035 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/PermissionContextFilter.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/PermissionContextFilter.java @@ -1,5 +1,6 @@ package io.dico.dicore.command; +import java.util.List; import java.util.Objects; public class PermissionContextFilter implements IContextFilter { @@ -106,4 +107,30 @@ public class PermissionContextFilter implements IContextFilter { return failMessage; } + /* + private fun getPermissionsOf(address: ICommandAddress) = getPermissionsOf(address, emptyArray(), mutableListOf()) + + private fun getPermissionsOf(address: ICommandAddress, path: Array, result: MutableList): List { + val command = address.command ?: return result + + var inherited = false + for (filter in command.contextFilters) { + when (filter) { + is PermissionContextFilter -> { + if (path.isEmpty()) result.add(filter.permission) + else if (filter.isInheritable) result.add(filter.getInheritedPermission(path)) + } + is InheritingContextFilter -> { + if (filter.priority == PERMISSION && address.hasParent() && !inherited) { + inherited = true + getPermissionsOf(address.parent, arrayOf(address.mainKey, *path), result) + } + } + } + } + + return result + } + */ + } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/RootCommandAddress.java b/dicore3/command/src/main/java/io/dico/dicore/command/RootCommandAddress.java index 10dade5..44f0540 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/RootCommandAddress.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/RootCommandAddress.java @@ -85,7 +85,8 @@ public class RootCommandAddress extends ModifiableCommandAddress implements ICom } } - private static void registerMember(Map map, String key, org.bukkit.command.Command value, boolean override) { + private static void registerMember(Map map, + String key, org.bukkit.command.Command value, boolean override) { if (override) { map.put(key, value); } else { @@ -147,15 +148,25 @@ public class RootCommandAddress extends ModifiableCommandAddress implements ICom ModifiableCommandAddress cur = this; ChildCommandAddress child; while (buffer.hasNext()) { - child = cur.getChild(buffer.next(), context); + int cursor = buffer.getCursor(); + + child = cur.getChild(context, buffer); + if (child == null + || (context.isTabComplete() && !buffer.hasNext()) || (child.hasCommand() && !child.getCommand().isVisibleTo(sender)) || (cur.hasCommand() && cur.getCommand().takePrecedenceOverSubcommand(buffer.peekPrevious(), buffer.getUnaffectingCopy()))) { - buffer.rewind(); + buffer.setCursor(cursor); break; } cur = child; + + context.setAddress(child); + if (child.hasCommand() && child.isCommandTrailing()) { + child.getCommand().initializeAndFilterContext(context); + child.getCommand().execute(context.getSender(), context); + } } return cur; @@ -173,7 +184,7 @@ public class RootCommandAddress extends ModifiableCommandAddress implements ICom @Override public boolean dispatchCommand(CommandSender sender, ArgumentBuffer buffer) { - ExecutionContext context = new ExecutionContext(sender, false); + ExecutionContext context = new ExecutionContext(sender, buffer, false); ModifiableCommandAddress targetAddress = null; @@ -189,8 +200,15 @@ public class RootCommandAddress extends ModifiableCommandAddress implements ICom } } - context.targetAcquired(targetAddress, target, buffer); - target.executeWithContext(context); + context.setCommand(target); + + if (!targetAddress.isCommandTrailing()) { + target.initializeAndFilterContext(context); + String message = target.execute(sender, context); + if (message != null && !message.isEmpty()) { + context.sendMessage(EMessageType.RESULT, message); + } + } } catch (Throwable t) { if (targetAddress == null) { @@ -214,15 +232,16 @@ public class RootCommandAddress extends ModifiableCommandAddress implements ICom @Override public List getTabCompletions(CommandSender sender, Location location, ArgumentBuffer buffer) { - ExecutionContext context = new ExecutionContext(sender, true); + ExecutionContext context = new ExecutionContext(sender, buffer, true); try { ICommandAddress target = getCommandTarget(context, buffer); List out; if (target.hasCommand()) { - context.targetAcquired(target, target.getCommand(), buffer); - out = target.getCommand().tabCompleteWithContext(context, location); + context.setCommand(target.getCommand()); + target.getCommand().initializeAndFilterContext(context); + out = target.getCommand().tabComplete(sender, context, location); } else { out = Collections.emptyList(); } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/annotation/PreprocessArgs.java b/dicore3/command/src/main/java/io/dico/dicore/command/annotation/PreprocessArgs.java index 40d6d73..57f53bd 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/annotation/PreprocessArgs.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/annotation/PreprocessArgs.java @@ -7,6 +7,7 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) +@Deprecated public @interface PreprocessArgs { String tokens() default "\"\""; diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/defaults/DefaultPageBuilder.java b/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/defaults/DefaultPageBuilder.java index f5b7cdb..a584e7e 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/defaults/DefaultPageBuilder.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/defaults/DefaultPageBuilder.java @@ -13,7 +13,8 @@ import java.util.ListIterator; public class DefaultPageBuilder implements IPageBuilder { @Override - public String getPage(List helpTopics, IPageLayout pageLayout, ICommandAddress target, Permissible viewer, ExecutionContext context, int pageNum, int pageLen) { + public String getPage(List helpTopics, IPageLayout pageLayout, ICommandAddress target, + Permissible viewer, ExecutionContext context, int pageNum, int pageLen) { if (pageLen <= 0 || pageNum < 0) { throw new IllegalArgumentException(); } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/insertion/HelpComponentInserter.java b/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/insertion/HelpComponentInserter.java index b043deb..f153165 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/insertion/HelpComponentInserter.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/insertion/HelpComponentInserter.java @@ -19,7 +19,7 @@ public class HelpComponentInserter extends HelpTopicModifier { @Override protected List modify(List components, ICommandAddress target, Permissible viewer, ExecutionContext context) { - int componentCount = components.size(); + // int componentCount = components.size(); for (int i = insertions.size() - 1; i >= 0; i--) { IInsertion insertion = insertions.get(i); diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentBuffer.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentBuffer.java index e063000..aa69730 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentBuffer.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentBuffer.java @@ -1,6 +1,8 @@ package io.dico.dicore.command.parameter; import io.dico.dicore.command.CommandException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -23,7 +25,7 @@ public class ArgumentBuffer extends AbstractList implements Iterator implements Iterator implements Iterator implements Iterator implements Iterator implements Iterator iterator() { + public @NotNull Iterator iterator() { return this; } @Override - public ListIterator listIterator() { + public @NotNull ListIterator listIterator() { return new ListIterator() { @Override public boolean hasNext() { @@ -243,13 +250,14 @@ public class ArgumentBuffer extends AbstractList implements Iterator implements Iterator= 0 && foundSectionCount >= count) return false; + while (currentIndex < args.length) { String arg = args[currentIndex]; if (arg == null) { @@ -127,9 +132,11 @@ public class ArgumentMergingPreProcessor implements IArgumentPreProcessor { sectionStart = -1; sectionEnd = -1; + + ++foundSectionCount; } - public String[] doProcess() { + String[] doProcess() { reset(); while (findNextSectionStart()) { @@ -155,6 +162,14 @@ public class ArgumentMergingPreProcessor implements IArgumentPreProcessor { return result; } + void updateBuffer(ArgumentBuffer buffer) { + if (count < 0) { + buffer.setCursor(start); + } else { + buffer.setCursor(currentIndex); + } + } + } } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ContextParser.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ContextParser.java index 3bfcf9b..a5afce5 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ContextParser.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ContextParser.java @@ -13,21 +13,27 @@ public class ContextParser { private final Parameter m_repeatedParam; private final List> m_indexedParams; private final int m_maxIndex; - private final int m_requiredIndex; + private final int m_maxRequiredIndex; - private Map m_valueMap = new HashMap<>(); - private Set m_parsedKeys = new HashSet<>(); + private Map m_valueMap; + private Set m_parsedKeys; private int m_completionCursor = -1; private Parameter m_completionTarget = null; - public ContextParser(ExecutionContext context) { - this.m_context = context; - this.m_buffer = context.getProcessedBuffer(); - this.m_paramList = context.getParameterList(); - this.m_repeatedParam = m_paramList.getRepeatedParameter(); - this.m_indexedParams = m_paramList.getIndexedParameters(); - this.m_maxIndex = m_indexedParams.size() - 1; - this.m_requiredIndex = m_paramList.getRequiredCount() - 1; + public ContextParser(ExecutionContext context, + ParameterList parameterList, + Map valueMap, + Set keySet) { + m_context = context; + m_paramList = parameterList; + m_valueMap = valueMap; + m_parsedKeys = keySet; + + m_buffer = context.getBuffer(); + m_repeatedParam = m_paramList.getRepeatedParameter(); + m_indexedParams = m_paramList.getIndexedParameters(); + m_maxIndex = m_indexedParams.size() - 1; + m_maxRequiredIndex = m_paramList.getRequiredCount() - 1; } public ExecutionContext getContext() { @@ -102,7 +108,7 @@ public class ContextParser { m_curParamIndex++; m_curParam = m_indexedParams.get(m_curParamIndex); prepareRepeatedParameterIfSet(); - requireInput = m_curParamIndex <= m_requiredIndex; + requireInput = m_curParamIndex <= m_maxRequiredIndex; } else if (m_buffer.hasNext()) { throw new CommandException("Too many arguments for /" + m_context.getAddress().getAddress()); @@ -146,7 +152,7 @@ public class ContextParser { private void prepareRepeatedParameterIfSet() throws CommandException { if (m_curParam != null && m_curParam == m_repeatedParam) { - if (m_curParam.isFlag() && m_curParamIndex < m_requiredIndex) { + if (m_curParam.isFlag() && m_curParamIndex < m_maxRequiredIndex) { Parameter requiredParam = m_indexedParams.get(m_curParamIndex + 1); reportParameterRequired(requiredParam); } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/IArgumentPreProcessor.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/IArgumentPreProcessor.java index b112367..0b8198e 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/IArgumentPreProcessor.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/IArgumentPreProcessor.java @@ -3,19 +3,26 @@ package io.dico.dicore.command.parameter; /** * An interface to process tokens such as quotes */ +@Deprecated public interface IArgumentPreProcessor { /** - * Preprocess the arguments without modifying the array. - * Might return the same array (in which case no changes were made). + * Preprocess the arguments contained within the given ArgumentBuffer. + * If no changes are made, this might return the same buffer. + * Any arguments preceding {@code buffer.getCursor()} will not be affected. * - * @param argStart the index within the array where the given arguments start (the part before that identifies the command) - * @param args the arguments + *

+ * If {@code count} is non-negative, it declares a limit on the number of arguments after preprocessing. + * In that case, the buffer's cursor is set to the index of the first argument following processed arguments. + *

+ * + * @param buffer the argument buffer + * @param count the maximum number of (processed) arguments * @return the arguments after preprocessing */ - String[] process(int argStart, String[] args); + ArgumentBuffer process(ArgumentBuffer buffer, int count); - IArgumentPreProcessor NONE = (argStart, args) -> args; + IArgumentPreProcessor NONE = (buffer, count) -> buffer; /** * Get an IArgumentPreProcessor that merges arguments between any two tokens @@ -31,3 +38,4 @@ public interface IArgumentPreProcessor { } } + diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ParameterList.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ParameterList.java index 459ced5..613d057 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ParameterList.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ParameterList.java @@ -5,10 +5,12 @@ import java.util.*; /** * IParameter definition for a command */ +@SuppressWarnings("UnusedReturnValue") public class ParameterList { + //private ParameterList parent; private List> indexedParameters; private Map> byName; - private IArgumentPreProcessor argumentPreProcessor = IArgumentPreProcessor.NONE; + //private IArgumentPreProcessor argumentPreProcessor = IArgumentPreProcessor.NONE; private int requiredCount = -1; private boolean repeatFinalParameter; @@ -18,12 +20,22 @@ public class ParameterList { // parameter is taken for repeating private boolean finalParameterMayBeFlag; + /* + public ParameterList(ParameterList parent) { + this(); + if (parent.repeatFinalParameter) { + throw new IllegalArgumentException("Parent may not have repeating parameters"); + } + this.parent = parent; + }*/ + public ParameterList() { this.indexedParameters = new ArrayList<>(); this.byName = new LinkedHashMap<>(); this.repeatFinalParameter = false; } + /* public IArgumentPreProcessor getArgumentPreProcessor() { return argumentPreProcessor; } @@ -31,7 +43,7 @@ public class ParameterList { public ParameterList setArgumentPreProcessor(IArgumentPreProcessor argumentPreProcessor) { this.argumentPreProcessor = argumentPreProcessor == null ? IArgumentPreProcessor.NONE : argumentPreProcessor; return this; - } + }*/ public boolean repeatFinalParameter() { return repeatFinalParameter; diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/EnumParameterType.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/EnumParameterType.java index e71c6cc..c23e09b 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/EnumParameterType.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/EnumParameterType.java @@ -20,7 +20,8 @@ public class EnumParameterType extends SimpleParameterType parameter, CommandSender sender, String input) throws CommandException { + @Override + protected E parse(Parameter parameter, CommandSender sender, String input) throws CommandException { for (E constant : universe) { if (constant.name().equalsIgnoreCase(input)) { return constant; @@ -30,7 +31,8 @@ public class EnumParameterType extends SimpleParameterType complete(Parameter parameter, CommandSender sender, Location location, ArgumentBuffer buffer) { + @Override + public List complete(Parameter parameter, CommandSender sender, Location location, ArgumentBuffer buffer) { String input = buffer.next().toUpperCase(); List result = new ArrayList<>(); for (E constant : universe) { diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterType.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterType.java index d89fd10..e1a62fa 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterType.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterType.java @@ -146,56 +146,4 @@ public abstract class ParameterType { } - public @interface Reference { - - /** - * The path to the static field holding the parameter type referred. - * - * @return The path - */ - String value(); - } - - public static class ReferenceUtil { - - private ReferenceUtil() { - - } - - - /** - * Get the ParameterType with the associated Reference - * - * @param ref the reference - * @return the parameter type object - * @throws IllegalArgumentException if the class is found, but the field doesn't exist. - * @throws IllegalStateException if this method fails to find the object for any other reason - */ - public static Object getReference(Reference ref) { - String[] path = ref.value().split("\\."); - if (path.length < 2) { - throw new IllegalStateException(); - } - - String fieldName = path[path.length - 1]; - String className = String.join(".", Arrays.copyOfRange(path, 0, path.length - 1)); - - Class clazz; - try { - clazz = Class.forName(className); - } catch (ClassNotFoundException ex) { - throw new IllegalArgumentException(ex); - } - - Object result = Reflection.getStaticFieldValue(clazz, fieldName); - - if (result == null) { - throw new IllegalStateException(); - } - - return result; - } - - } - } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/predef/DefaultGroupCommand.java b/dicore3/command/src/main/java/io/dico/dicore/command/predef/DefaultGroupCommand.java index 3988da2..e664cef 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/predef/DefaultGroupCommand.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/predef/DefaultGroupCommand.java @@ -38,9 +38,9 @@ public class DefaultGroupCommand extends PredefinedCommand noArgumentFilter = new IContextFilter() { @Override public void filterContext(ExecutionContext context) throws CommandException { - if (context.getProcessedBuffer().hasNext()) { + if (context.getBuffer().hasNext()) { throw new CommandException("No such command: /" + context.getAddress().getAddress() - + " " + context.getProcessedBuffer().next()); + + " " + context.getBuffer().next()); } } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ICommandInterceptor.java b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ICommandInterceptor.java new file mode 100644 index 0000000..67b65e4 --- /dev/null +++ b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ICommandInterceptor.java @@ -0,0 +1,36 @@ +package io.dico.dicore.command.registration.reflect; + +import io.dico.dicore.command.ExecutionContext; + +import java.lang.reflect.Method; + +public interface ICommandInterceptor { + + /** + * Get the receiver of the command, if applicable. + * A command has a receiver if its first parameter implements {@link ICommandReceiver} + * and its instance object implements this interface. + * + * @param context the context of execution + * @param target the method of the command + * @param cmdName the name of the command + * @return the receiver + */ + default ICommandReceiver getReceiver(ExecutionContext context, Method target, String cmdName) { + return null; + } + + /** + * If applicable, get the coroutine context to use in suspend functions (Kotlin only). + * The return type is object to avoid depending on the kotlin runtime. + * + * @param context the context of execution + * @param target the method of the command + * @param cmdName the name of the command + * @return the coroutine context + */ + default Object getCoroutineContext(ExecutionContext context, Method target, String cmdName) { + return null; + } + +} diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ICommandReceiver.java b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ICommandReceiver.java new file mode 100644 index 0000000..bdcb568 --- /dev/null +++ b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ICommandReceiver.java @@ -0,0 +1,5 @@ +package io.dico.dicore.command.registration.reflect; + +public interface ICommandReceiver { + +} diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveCommand.java b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveCommand.java index 591d824..ee90efe 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveCommand.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveCommand.java @@ -15,6 +15,8 @@ public final class ReflectiveCommand extends Command { private final Method method; private final Object instance; private String[] parameterOrder; + + // hasContinuation | hasContext | hasSender | hasReceiver private final int flags; ReflectiveCommand(IParameterTypeSelector selector, Method method, Object instance) throws CommandParseException { @@ -56,6 +58,8 @@ public final class ReflectiveCommand extends Command { return instance; } + public String getCmdName() { return cmdAnnotation.value(); } + void setParameterOrder(String[] parameterOrder) { this.parameterOrder = parameterOrder; } @@ -86,18 +90,24 @@ public final class ReflectiveCommand extends Command { Object[] args = new Object[parameterOrder.length + start]; int i = 0; - if ((flags & 1) != 0) { + + int mask = 1; + if ((flags & mask) != 0) { try { - args[i++] = ((ICommandReceiver.Factory) instance).getReceiver(context, method, cmdAnnotation.value()); + args[i++] = ((ICommandInterceptor) instance).getReceiver(context, method, getCmdName()); } catch (Exception ex) { handleException(ex); return null; // unreachable } } - if ((flags & 2) != 0) { + + mask <<= 1; + if ((flags & mask) != 0) { args[i++] = sender; } - if ((flags & 4) != 0) { + + mask <<= 1; + if ((flags & mask) != 0) { args[i++] = context; } @@ -105,11 +115,12 @@ public final class ReflectiveCommand extends Command { args[i] = context.get(parameterOrder[i - start]); } - if (!isSuspendFunction()) { - return callSynchronously(args); + mask <<= 1; + if ((flags & mask) != 0) { + return callAsCoroutine(context, args); } - return callAsCoroutine(context, args); + return callSynchronously(args); } private boolean isSuspendFunction() { @@ -137,9 +148,6 @@ public final class ReflectiveCommand extends Command { if (returned instanceof String) { return (String) returned; } - if (returned instanceof CommandResult) { - return ((CommandResult) returned).getMessage(); - } return null; } @@ -160,7 +168,7 @@ public final class ReflectiveCommand extends Command { } private String callAsCoroutine(ExecutionContext context, Object[] args) { - return KotlinReflectiveRegistrationKt.callAsCoroutine(this, (ICommandReceiver.Factory) instance, context, args); + return KotlinReflectiveRegistrationKt.callAsCoroutine(this, (ICommandInterceptor) instance, context, args); } } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java index 1279c2b..1405414 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java @@ -3,7 +3,6 @@ package io.dico.dicore.command.registration.reflect; import io.dico.dicore.command.*; import io.dico.dicore.command.annotation.*; import io.dico.dicore.command.annotation.GroupMatchedCommands.GroupEntry; -import io.dico.dicore.command.parameter.IArgumentPreProcessor; import io.dico.dicore.command.parameter.Parameter; import io.dico.dicore.command.parameter.ParameterList; import io.dico.dicore.command.parameter.type.IParameterTypeSelector; @@ -199,15 +198,20 @@ public class ReflectiveRegistration { static int parseCommandAttributes(IParameterTypeSelector selector, Method method, ReflectiveCommand command, java.lang.reflect.Parameter[] parameters) throws CommandParseException { ParameterList list = command.getParameterList(); + boolean hasReceiverParameter = false; boolean hasSenderParameter = false; + boolean hasContextParameter = false; + boolean hasContinuationParameter = false; + int start = 0; - Class firstParameterType = null; + int end = parameters.length; + Class senderParameterType = null; if (parameters.length > start - && command.getInstance() instanceof ICommandReceiver.Factory - && ICommandReceiver.class.isAssignableFrom(firstParameterType = parameters[start].getType())) { + && command.getInstance() instanceof ICommandInterceptor + && ICommandReceiver.class.isAssignableFrom(parameters[start].getType())) { hasReceiverParameter = true; start++; } @@ -217,20 +221,18 @@ public class ReflectiveRegistration { start++; } - boolean hasContextParameter = false; if (parameters.length > start && parameters[start].getType() == ExecutionContext.class) { hasContextParameter = true; start++; } + if (parameters.length > start && parameters[end - 1].getType().getName().equals("kotlin.coroutines.Continuation")) { + hasContinuationParameter = true; + end--; + } + String[] parameterNames = lookupParameterNames(method, parameters, start); - for (int i = start, n = parameters.length; i < n; i++) { - if (parameters[i].getType().getName().equals("kotlin.coroutines.Continuation")) { - List temp = new ArrayList<>(Arrays.asList(parameterNames)); - temp.remove(i - start); - parameterNames = temp.toArray(new String[0]); - continue; - } + for (int i = start, n = end; i < n; i++) { Parameter parameter = parseParameter(selector, method, parameters[i], parameterNames[i - start]); list.addParameter(parameter); } @@ -256,11 +258,12 @@ public class ReflectiveRegistration { list.setRequiredCount(list.getIndexedParameters().size()); } + /* PreprocessArgs preprocessArgs = method.getAnnotation(PreprocessArgs.class); if (preprocessArgs != null) { IArgumentPreProcessor preProcessor = IArgumentPreProcessor.mergeOnTokens(preprocessArgs.tokens(), preprocessArgs.escapeChar()); list.setArgumentPreProcessor(preProcessor); - } + }*/ Desc desc = method.getAnnotation(Desc.class); if (desc != null) { @@ -286,7 +289,16 @@ public class ReflectiveRegistration { list.setRepeatFinalParameter(parameters.length > start && parameters[parameters.length - 1].isVarArgs()); list.setFinalParameterMayBeFlag(true); - return (hasSenderParameter ? 2 : 0) | (hasContextParameter ? 4 : 0) | (hasReceiverParameter ? 1 : 0); + + int flags = 0; + if (hasContinuationParameter) flags |= 1; + flags <<= 1; + if (hasContextParameter) flags |= 1; + flags <<= 1; + if (hasSenderParameter) flags |= 1; + flags <<= 1; + if (hasReceiverParameter) flags |= 1; + return flags; } public static int parseCommandAttributes(IParameterTypeSelector selector, Method method, ReflectiveCommand command) throws CommandParseException { @@ -373,7 +385,7 @@ public class ReflectiveRegistration { @Cmd({"tp", "tpto"}) @RequirePermissions("teleport.self") - public (static) String|void|CommandResult onCommand(Player sender, Player target, @Flag("force", permission = "teleport.self.force") boolean force) { + public (static) String|void onCommand(Player sender, Player target, @Flag("force", permission = "teleport.self.force") boolean force) { Validate.isTrue(force || !hasTpToggledOff(target), "Target has teleportation disabled. Use -force to ignore"); sender.teleport(target); //return diff --git a/dicore3/command/src/main/kotlin/io/dico/dicore/command/registration/reflect/KotlinReflectiveRegistration.kt b/dicore3/command/src/main/kotlin/io/dico/dicore/command/registration/reflect/KotlinReflectiveRegistration.kt index c4aa134..2ef6e39 100644 --- a/dicore3/command/src/main/kotlin/io/dico/dicore/command/registration/reflect/KotlinReflectiveRegistration.kt +++ b/dicore3/command/src/main/kotlin/io/dico/dicore/command/registration/reflect/KotlinReflectiveRegistration.kt @@ -1,9 +1,6 @@ package io.dico.dicore.command.registration.reflect -import io.dico.dicore.command.CommandException -import io.dico.dicore.command.EMessageType -import io.dico.dicore.command.ExecutionContext -import io.dico.dicore.command.ICommandReceiver +import io.dico.dicore.command.* import kotlinx.coroutines.CoroutineStart.UNDISPATCHED import kotlinx.coroutines.Deferred import kotlinx.coroutines.GlobalScope @@ -22,15 +19,16 @@ fun isSuspendFunction(method: Method): Boolean { fun callAsCoroutine( command: ReflectiveCommand, - factory: ICommandReceiver.Factory, + factory: ICommandInterceptor, context: ExecutionContext, args: Array ): String? { + val coroutineContext = factory.getCoroutineContext(context, command.method, command.cmdName) as CoroutineContext // UNDISPATCHED causes the handler to run until the first suspension point on the current thread, // meaning command handlers that don't have suspension points will run completely synchronously. // Tasks that take time to compute should suspend the coroutine and resume on another thread. - val job = GlobalScope.async(context = factory.coroutineContext as CoroutineContext, start = UNDISPATCHED) { + val job = GlobalScope.async(context = coroutineContext, start = UNDISPATCHED) { suspendCoroutineUninterceptedOrReturn { cont -> command.method.invoke(command.instance, *args, cont.intercepted()) } @@ -41,12 +39,12 @@ fun callAsCoroutine( } job.invokeOnCompletion { - val cc = context.address.chatHandler + val chatHandler = context.address.chatHandler try { val result = job.getResult() - cc.sendMessage(context.sender, EMessageType.RESULT, result) + chatHandler.sendMessage(context.sender, EMessageType.RESULT, result) } catch (ex: Throwable) { - cc.handleException(context.sender, context, ex) + chatHandler.handleException(context.sender, context, ex) } } diff --git a/dicore3/command/src/test/java/io/dico/dicore/command/example/ParameterInfoObjectExample.java b/dicore3/command/src/test/java/io/dico/dicore/command/example/ParameterInfoObjectExample.java new file mode 100644 index 0000000..1cd4e23 --- /dev/null +++ b/dicore3/command/src/test/java/io/dico/dicore/command/example/ParameterInfoObjectExample.java @@ -0,0 +1,73 @@ +package io.dico.dicore.command.example; + +import io.dico.dicore.command.CommandBuilder; +import io.dico.dicore.command.CommandException; +import io.dico.dicore.command.Validate; +import io.dico.dicore.command.annotation.Cmd; +import io.dico.dicore.command.parameter.ArgumentBuffer; +import io.dico.dicore.command.parameter.Parameter; +import io.dico.dicore.command.parameter.type.ParameterConfig; +import io.dico.dicore.command.parameter.type.ParameterType; +import org.bukkit.command.CommandSender; + +public class ParameterInfoObjectExample { + + private @interface ParentPermission { + String value(); + } + + static class MyInfoObject { + public static final ParameterConfig config = new ParameterConfig() { + @Override + protected MyInfoObject toParameterInfo(ParentPermission annotation) { + return new MyInfoObject(annotation.value()); + } + }; + + private String permissionParent; + + MyInfoObject(String permissionParent) { + this.permissionParent = permissionParent; + } + + public String getPermissionParent() { + return permissionParent; + } + } + + static class MyParameterType extends ParameterType { + + public MyParameterType() { + super(String.class, MyInfoObject.config); + } + + @Override + public String parse(Parameter parameter, CommandSender sender, ArgumentBuffer buffer) throws CommandException { + String value = buffer.next(); + + MyInfoObject mio = parameter.getParamInfo(); + if (mio != null) { + String permission = mio.permissionParent + "." + value; + Validate.isAuthorized(sender, permission); + } + + return value; + } + } + + static class MyCommands { + + @Cmd("test") + Object cmdTest(@ParentPermission("test.permission") String value) { + return "You have permission to use the argument '" + value + "'!"; + } + + } + + static void main(String[] args) { + new CommandBuilder() + .addParameterType(false, new MyParameterType()) + .registerCommands(new MyCommands()); + } + +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..1948b90 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..d2c45a4 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt b/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt index bcc7997..eaa9f57 100644 --- a/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt +++ b/src/main/kotlin/io/dico/parcels2/command/AbstractParcelCommands.kt @@ -1,9 +1,8 @@ package io.dico.parcels2.command -import io.dico.dicore.command.CommandException -import io.dico.dicore.command.EMessageType -import io.dico.dicore.command.ExecutionContext -import io.dico.dicore.command.ICommandReceiver +import io.dico.dicore.command.* +import io.dico.dicore.command.registration.reflect.ICommandInterceptor +import io.dico.dicore.command.registration.reflect.ICommandReceiver import io.dico.parcels2.* import io.dico.parcels2.PlayerProfile.Real import io.dico.parcels2.PlayerProfile.Unresolved @@ -13,13 +12,16 @@ import org.bukkit.entity.Player import org.bukkit.plugin.Plugin import java.lang.reflect.Method -abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandReceiver.Factory { - override fun getPlugin(): Plugin = plugin +abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandInterceptor { override fun getReceiver(context: ExecutionContext, target: Method, cmdName: String): ICommandReceiver { return getParcelCommandReceiver(plugin.parcelProvider, context, target, cmdName) } + override fun getCoroutineContext(context: ExecutionContext?, target: Method?, cmdName: String?): Any { + return plugin.coroutineContext + } + protected fun checkConnected(action: String) { if (!plugin.storage.isConnected) err("Parcels cannot $action right now because of a database error") } @@ -57,8 +59,6 @@ abstract class AbstractParcelCommands(val plugin: ParcelsPlugin) : ICommandRecei .format(progress * 100, elapsedTime / 1000.0) ) } - - override fun getCoroutineContext() = plugin.coroutineContext } fun err(message: String): Nothing = throw CommandException(message) \ No newline at end of file diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt index 2777b7f..721ce2d 100644 --- a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt +++ b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt @@ -1,6 +1,7 @@ package io.dico.parcels2.command import io.dico.dicore.command.* +import io.dico.dicore.command.parameter.ArgumentBuffer import io.dico.dicore.command.predef.DefaultGroupCommand import io.dico.dicore.command.registration.reflect.ReflectiveRegistration import io.dico.parcels2.Interactables @@ -107,10 +108,12 @@ class SpecialCommandAddress : ChildCommandAddress() { } } + // h:1 @Throws(CommandException::class) - override fun getChild(key: String, context: ExecutionContext): ChildCommandAddress? { + override fun getChild(context: ExecutionContext, buffer: ArgumentBuffer): ChildCommandAddress? { speciallyParsedIndex = null + val key = buffer.next() ?: return null for (specialKey in speciallyTreatedKeys) { if (key.startsWith(specialKey)) { val result = getChild(specialKey.substring(0, specialKey.length - 1)) diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt index 8f6dabc..15548b4 100644 --- a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt +++ b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandReceivers.kt @@ -2,7 +2,7 @@ package io.dico.parcels2.command import io.dico.dicore.command.CommandException import io.dico.dicore.command.ExecutionContext -import io.dico.dicore.command.ICommandReceiver +import io.dico.dicore.command.registration.reflect.ICommandReceiver import io.dico.dicore.command.Validate import io.dico.parcels2.* import io.dico.parcels2.Privilege.* diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt index 736e568..a9f5498 100644 --- a/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt +++ b/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt @@ -30,7 +30,7 @@ class ParcelParameterType(val parcelProvider: ParcelProvider) : ParameterType)?([0-9]+):([0-9]+)") override fun parse(parameter: Parameter, sender: CommandSender, buffer: ArgumentBuffer): Parcel { - val matchResult = regex.matchEntire(buffer.next()) + val matchResult = regex.matchEntire(buffer.next()!!) ?: invalidInput(parameter, "must match (w->)?a:b (/${regex.pattern}/)") val world = parcelProvider.getTargetWorld(matchResult.groupValues[2], sender, parameter) @@ -66,7 +66,7 @@ class ProfileParameterType : ParameterType(PlayerProfile::cl val allowReal = (info and REAL) != 0 val allowFake = (info and FAKE) != 0 - val input = buffer.next() + val input = buffer.next()!! return PlayerProfile.byName(input, allowReal, allowFake) } diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt index 70a8dda..8891912 100644 --- a/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt +++ b/src/main/kotlin/io/dico/parcels2/command/ParcelTarget.kt @@ -91,7 +91,7 @@ sealed class ParcelTarget(val world: ParcelWorld, val parsedKind: Int, val isDef ParameterType(ParcelTarget::class.java, TargetKind) { override fun parse(parameter: Parameter, sender: CommandSender, buffer: ArgumentBuffer): ParcelTarget { - var input = buffer.next() + var input = buffer.next()!! val worldString = input.substringBefore("/", missingDelimiterValue = "") input = input.substringAfter("/") diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt index e9ec148..9e43c05 100644 --- a/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt +++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelGenerator.kt @@ -279,7 +279,6 @@ class DefaultParcelGenerator( val region = getRegion(parcel) val blocks = parcelTraverser.traverseRegion(region) val blockCount = region.blockCount.toDouble() - val world = world val floorHeight = o.floorHeight val airType = airType diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelProviderImpl.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelProviderImpl.kt index 74545d6..48a7fee 100644 --- a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelProviderImpl.kt +++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelProviderImpl.kt @@ -50,7 +50,7 @@ class ParcelProviderImpl(val plugin: ParcelsPlugin) : ParcelProvider { return } - //val newlyCreatedWorlds = mutableListOf() + val newlyCreatedWorlds = mutableListOf() for ((worldName, worldOptions) in options.worlds.entries) { var parcelWorld = _worlds[worldName] if (parcelWorld != null) continue @@ -70,7 +70,7 @@ class ParcelProviderImpl(val plugin: ParcelsPlugin) : ParcelProvider { val time = DateTime.now() plugin.storage.setWorldCreationTime(parcelWorld.id, time) parcelWorld.creationTime = time - //newlyCreatedWorlds.add(parcelWorld) + newlyCreatedWorlds.add(parcelWorld) } else { GlobalScope.launch(context = Dispatchers.Unconfined) { parcelWorld.creationTime = plugin.storage.getWorldCreationTime(parcelWorld.id).await() ?: DateTime.now() @@ -80,10 +80,10 @@ class ParcelProviderImpl(val plugin: ParcelsPlugin) : ParcelProvider { _worlds[worldName] = parcelWorld } - loadStoredData() + loadStoredData(newlyCreatedWorlds.toSet()) } - private fun loadStoredData() { + private fun loadStoredData(newlyCreatedWorlds: Collection = emptyList()) { plugin.launch(Dispatchers.Default) { val migration = plugin.options.migration if (migration.enabled) { @@ -105,9 +105,8 @@ class ParcelProviderImpl(val plugin: ParcelsPlugin) : ParcelProvider { val channel = plugin.storage.transmitAllParcelData() while (true) { val (id, data) = channel.receiveOrNull() ?: break - if (data == null) continue val parcel = getParcelById(id) ?: continue - parcel.copyData(data, callerIsDatabase = true) + data?.let { parcel.copyData(it, callerIsDatabase = true) } } } diff --git a/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt b/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt index 04941b4..59d10e7 100644 --- a/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt +++ b/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt @@ -85,8 +85,6 @@ class ParcelListeners( newTo = newTo.add(it, delta * 100 * if (it == Dimension.Y) 0.5 else speed) } - - event.to = Location( toLoc.world, newTo.x, newTo.y.clampMin(0.0).clampMax(255.0), newTo.z, diff --git a/src/main/kotlin/io/dico/parcels2/storage/Hikari.kt b/src/main/kotlin/io/dico/parcels2/storage/Hikari.kt index d1500d5..480d533 100644 --- a/src/main/kotlin/io/dico/parcels2/storage/Hikari.kt +++ b/src/main/kotlin/io/dico/parcels2/storage/Hikari.kt @@ -32,7 +32,7 @@ fun getHikariConfig(dialectName: String, username = dco.username password = dco.password connectionTimeout = 15000 - leakDetectionThreshold = 30000 + leakDetectionThreshold = 10000 connectionTestQuery = "SELECT 1" -- cgit v1.2.3