From ed3c85951a768a4f151d44a8b9c63f4a6175c756 Mon Sep 17 00:00:00 2001 From: Dico Date: Wed, 26 Sep 2018 12:38:55 +0100 Subject: Tweaks --- .../io/dico/dicore/command/IContextFilter.java | 3 - .../parameter/ArgumentMergingPreProcessor.java | 162 +++++++++++++++++++++ .../command/parameter/IArgumentPreProcessor.java | 95 +----------- .../reflect/KotlinReflectiveRegistration.kt | 7 - .../command/ParcelOptionsInteractCommand.kt | 36 +++-- 5 files changed, 190 insertions(+), 113 deletions(-) create mode 100644 dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentMergingPreProcessor.java diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/IContextFilter.java b/dicore3/command/src/main/java/io/dico/dicore/command/IContextFilter.java index 4a4c06d..5c05e27 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/IContextFilter.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/IContextFilter.java @@ -5,9 +5,6 @@ import io.dico.dicore.exceptions.checkedfunctions.CheckedRunnable; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; -import java.util.List; -import java.util.Objects; - public interface IContextFilter extends Comparable { /** diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentMergingPreProcessor.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentMergingPreProcessor.java new file mode 100644 index 0000000..5f7b81d --- /dev/null +++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/ArgumentMergingPreProcessor.java @@ -0,0 +1,162 @@ +package io.dico.dicore.command.parameter; + +public class ArgumentMergingPreProcessor implements IArgumentPreProcessor { + private final String tokens; + private final char escapeChar; + + public ArgumentMergingPreProcessor(String tokens, char escapeChar) { + if ((tokens.length() & 1) != 0 || tokens.isEmpty()) throw new IllegalArgumentException(); + this.tokens = tokens; + this.escapeChar = escapeChar; + } + + @Override + public String[] process(int argStart, String[] args) { + if (!(0 <= argStart && argStart <= args.length)) { + throw new IndexOutOfBoundsException(); + } + + Parser parser = new Parser(argStart, args.clone()); + return parser.doProcess(); + } + + private class Parser { + private final int argStart; + private final String[] args; + + private int currentIndex; + private int sectionStart; + private char closingToken; + private int sectionEnd; + private int removeCount; + + Parser(int argStart, String[] args) { + this.argStart = argStart; + this.args = args; + } + + private void reset() { + removeCount = 0; + closingToken = 0; + sectionStart = -1; + sectionEnd = -1; + currentIndex = argStart; + } + + private boolean findNextSectionStart() { + while (currentIndex < args.length) { + String arg = args[currentIndex]; + if (arg == null) { + throw new IllegalArgumentException(); + } + + if (arg.isEmpty()) { + ++currentIndex; + continue; + } + + int openingTokenIndex = tokens.indexOf(arg.charAt(0)); + if (openingTokenIndex == -1 || (openingTokenIndex & 1) != 0) { + ++currentIndex; + continue; + } + + // found + closingToken = tokens.charAt(openingTokenIndex | 1); + sectionStart = currentIndex; + return true; + } + + return false; + } + + private boolean findNextSectionEnd() { + while (currentIndex < args.length) { + String arg = args[currentIndex]; + if (arg == null) { + throw new IllegalArgumentException(); + } + + if (arg.isEmpty() + || arg.charAt(arg.length() - 1) != closingToken + || (sectionStart == currentIndex && arg.length() == 1)) { + ++currentIndex; + continue; + } + + if (escapeChar != 0 + && arg.length() > 1 + && arg.charAt(arg.length() - 2) == escapeChar) { + // escaped + ++currentIndex; + continue; + } + + // found + closingToken = 0; + sectionEnd = currentIndex; + ++currentIndex; + return true; + } + + return false; + } + + private void processFoundSection() { + if (sectionStart == sectionEnd) { + String arg = args[sectionStart]; + args[sectionStart] = arg.substring(1, arg.length() - 1); + return; + } + + removeCount += sectionEnd - sectionStart; + + StringBuilder sb = new StringBuilder(); + sb.append(args[sectionStart].substring(1)); + + for (int i = sectionStart + 1; i < sectionEnd; i++) { + sb.append(' '); + sb.append(args[i]); + args[i] = null; + } + sb.append(' '); + sb.append(args[sectionEnd].substring(0, args[sectionEnd].length() - 1)); + args[sectionEnd] = null; + + args[sectionStart] = sb.toString(); + + sectionStart = -1; + sectionEnd = -1; + } + + public String[] doProcess() { + reset(); + + while (findNextSectionStart()) { + if (findNextSectionEnd()) { + processFoundSection(); + } else { + currentIndex = sectionStart + 1; + } + } + + if (removeCount == 0) { + return args; + } + + String[] result = new String[args.length - removeCount]; + int i = 0; + for (String arg : args) { + if (arg != null) { + result[i++] = arg; + } + } + + return result; + } + + } + +} + + 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 4ac9bd3..b112367 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 @@ -27,100 +27,7 @@ public interface IArgumentPreProcessor { * @return The IArgumentPreProcessor */ static IArgumentPreProcessor mergeOnTokens(String tokens, char escapeChar) { - if (tokens.isEmpty() || (tokens.length() & 1) != 0) { - throw new IllegalArgumentException(); - } - - return (argStart, args) -> { - if (!(0 <= argStart && argStart <= args.length)) { - throw new IndexOutOfBoundsException(); - } - - args = args.clone(); - int removeCount = 0; - int closingTokenIdx = 0; - int sectionStart = -1; - - for (int i = argStart; i < args.length; i++) { - String arg = args[i]; - if (arg == null || arg.isEmpty()) { - continue; - } - - if (closingTokenIdx != 0) { - int idx = tokens.indexOf(arg.charAt(arg.length() - 1)); - if (idx == closingTokenIdx) { - - // count escape chars - int index = arg.length() - 1; - int count = 0; - while (index > 0 && arg.charAt(--index) == escapeChar) { - count++; - } - - // remove the final char plus half the count, rounding upwards. - args[i] = arg.substring(0, args.length - 1 - (count + 1) / 2); - - if ((count & 1) == 0) { - // not escaped - StringBuilder concat = new StringBuilder(args[sectionStart].substring(1)); - for (int j = sectionStart + 1; j <= i; j++) { - concat.append(' ').append(args[j]); - args[j] = null; - removeCount++; - } - - args[sectionStart] = concat.toString(); - - sectionStart = -1; - closingTokenIdx = 0; - - } else { - // it's escaped - // add final char because it was escaped - args[i] += tokens.charAt(closingTokenIdx); - - } - } - - if (i == args.length - 1) { - // if the closing token isn't found, reset state and start from the index subsequent to the one where the opener was found - // it should also undo removal of any escapes... it doesn't do that - i = sectionStart + 1; - closingTokenIdx = 0; - sectionStart = -1; - } - - continue; - } - - int idx = tokens.indexOf(arg.charAt(0)); - if (idx == -1 || (idx & 1) != 0) { - continue; - } - - closingTokenIdx = idx | 1; - sectionStart = i; - - // make sure to check from the current index for a closer - i--; - } - - if (removeCount == 0) { - return args; - } - - String[] result = new String[args.length - removeCount]; - int i = 0; - for (String arg : args) { - if (arg != null) { - result[i++] = arg; - } - } - - return result; - }; - + return new ArgumentMergingPreProcessor(tokens, escapeChar); } } 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 c09088e..6fac845 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 @@ -66,10 +66,3 @@ private fun Deferred.getResult(): String? { } return ReflectiveCommand.getResult(getCompleted(), null) } - -fun getNonPrimitiveClass(clazz: Class<*>): Class<*>? { - return if (clazz.isPrimitive) - clazz.kotlin.javaObjectType - else - null -} \ No newline at end of file diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt index 8ba2d93..5c38b06 100644 --- a/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt +++ b/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt @@ -1,9 +1,6 @@ package io.dico.parcels2.command -import io.dico.dicore.command.Command -import io.dico.dicore.command.CommandException -import io.dico.dicore.command.ExecutionContext -import io.dico.dicore.command.IContextFilter +import io.dico.dicore.command.* import io.dico.dicore.command.parameter.type.ParameterTypes import io.dico.parcels2.Interactables import io.dico.parcels2.ParcelProvider @@ -14,17 +11,38 @@ import org.bukkit.entity.Player class ParcelOptionsInteractCommand(val parcelProvider: ParcelProvider) : Command() { init { + setShortDescription("View and/or change the setting") + setDescription(shortDescription) addContextFilter(IContextFilter.PLAYER_ONLY) addContextFilter(IContextFilter.INHERIT_PERMISSIONS) - addParameter("allowed", "allowed", ParameterTypes.BOOLEAN) + addParameter("allowed", "new setting", ParameterTypes.BOOLEAN) + requiredParameters(0) } override fun execute(sender: CommandSender, context: ExecutionContext): String? { - val parcel = parcelProvider.getParcelRequired(sender as Player, Privilege.CAN_MANAGE) - val interactableClassName = context.address.mainKey - val allowed: Boolean = context.get("allowed") - val change = parcel.interactableConfig.setInteractable(Interactables[interactableClassName], allowed) + val interactableClass = Interactables[context.address.mainKey] + val allowed: Boolean? = context.get("allowed") + val parcel = parcelProvider.getParcelRequired(sender as Player, + if (allowed == null) Privilege.DEFAULT else Privilege.CAN_MANAGE) + + if (allowed == null) { + val setting = parcel.interactableConfig.isInteractable(interactableClass) + val default = setting == interactableClass.interactableByDefault + + val canColor = context.address.chatController.getChatFormatForType(EMessageType.BAD_NEWS) + val cannotColor = context.address.chatController.getChatFormatForType(EMessageType.GOOD_NEWS) + val resetColor = context.address.chatController.getChatFormatForType(EMessageType.RESULT) + + val settingString = (if (setting) "${canColor}can" else "${cannotColor}cannot") + resetColor + val defaultString = if (default) " (default)" else "" + + return "Players $settingString interact with ${interactableClass.name} on this parcel$defaultString" + } + + val change = parcel.interactableConfig.setInteractable(interactableClass, allowed) + + val interactableClassName = interactableClass.name return when { allowed && change -> "Other players can now interact with $interactableClassName" allowed && !change -> err("Other players could already interact with $interactableClassName") -- cgit v1.2.3