Archived
0

More commandlib tweaks

This commit is contained in:
Dico
2018-09-27 09:03:28 +01:00
parent f28e4393db
commit 09aaa9ff72
27 changed files with 68 additions and 333 deletions

View File

@@ -91,18 +91,18 @@ public abstract class Command {
* ---- CONTEXT FILTERS ----
* Filter the contexts. For example, if the sender must be a player but it's the console,
* throw a CommandException describing the problem.
* <p>
* The index of the first element in contextFilters whose priority is POST_PARAMETERS
* Computed by {@link #computeContextFilterPostParameterIndex()}
*/
private transient int contextFilterPostParameterIndex;
private transient int postParameterFilterCount = 0;
public Command addContextFilter(IContextFilter contextFilter) {
Objects.requireNonNull(contextFilter);
if (!contextFilters.contains(contextFilter)) {
contextFilters.add(contextFilter);
contextFilters.sort(null);
computeContextFilterPostParameterIndex();
if (contextFilter.getPriority().compareTo(Priority.POST_PARAMETERS) >= 0) {
postParameterFilterCount++;
}
}
return this;
}
@@ -114,19 +114,11 @@ public abstract class Command {
public Command removeContextFilter(IContextFilter contextFilter) {
boolean ret = contextFilters.remove(contextFilter);
if (ret) {
computeContextFilterPostParameterIndex();
}
return this;
}
private void computeContextFilterPostParameterIndex() {
List<IContextFilter> contextFilters = this.contextFilters;
contextFilterPostParameterIndex = 0;
for (int i = contextFilters.size() - 1; i >= 0; i--) {
if (contextFilters.get(i).getPriority() != Priority.POST_PARAMETERS) {
contextFilterPostParameterIndex = i + 1;
if (contextFilter.getPriority().compareTo(Priority.POST_PARAMETERS) >= 0) {
postParameterFilterCount--;
}
}
return this;
}
// ---- CONTROL FLOW IN COMMAND TREES ----
@@ -154,7 +146,7 @@ public abstract class Command {
public void executeWithContext(ExecutionContext context) throws CommandException {
//System.out.println("In Command.execute(sender, caller, buffer)#try{");
int i, n;
for (i = 0, n = contextFilterPostParameterIndex; i < n; i++) {
for (i = 0, n = contextFilters.size() - postParameterFilterCount; i < n; i++) {
contextFilters.get(i).filterContext(context);
}
@@ -183,7 +175,7 @@ public abstract class Command {
public List<String> tabCompleteWithContext(ExecutionContext context, Location location) throws CommandException {
int i, n;
for (i = 0, n = contextFilterPostParameterIndex; i < n; i++) {
for (i = 0, n = contextFilters.size() - postParameterFilterCount; i < n; i++) {
contextFilters.get(i).filterContext(context);
}

View File

@@ -1,6 +1,6 @@
package io.dico.dicore.command;
import io.dico.dicore.command.chat.Formatting;
import io.dico.dicore.Formatting;
import io.dico.dicore.command.parameter.ArgumentBuffer;
import io.dico.dicore.command.parameter.ContextParser;
import io.dico.dicore.command.parameter.Parameter;

View File

@@ -78,7 +78,9 @@ public class RootCommandAddress extends ModifiableCommandAddress implements ICom
}
private static void debugChildren(ModifiableCommandAddress address) {
for (ModifiableCommandAddress child : new HashSet<ModifiableCommandAddress>(address.getChildren().values())) {
Collection<String> keys = address.getChildrenMainKeys();
for (String key : keys) {
ChildCommandAddress child = address.getChild(key);
System.out.println(child.getAddress());
debugChildren(child);
}
@@ -180,10 +182,10 @@ public class RootCommandAddress extends ModifiableCommandAddress implements ICom
targetAddress = getCommandTarget(context, buffer);
Command target = targetAddress.getCommand();
if (target == null || target instanceof DefaultGroupCommand) {
if (target == null) {
if (targetAddress.hasHelpCommand()) {
target = targetAddress.getHelpCommand().getCommand();
} else if (target == null){
} else {
return false;
}
}

View File

@@ -1,5 +1,6 @@
package io.dico.dicore.command.chat;
import io.dico.dicore.Formatting;
import io.dico.dicore.command.CommandException;
import io.dico.dicore.command.EMessageType;
import io.dico.dicore.command.ExecutionContext;

View File

@@ -1,278 +0,0 @@
package io.dico.dicore.command.chat;
import gnu.trove.map.TCharObjectMap;
import gnu.trove.map.hash.TCharObjectHashMap;
public final class Formatting implements CharSequence {
public static final char FORMAT_CHAR = '\u00a7';
private static final TCharObjectMap<Formatting> singleCharInstances = new TCharObjectHashMap<>(16, .5F, '\0');
public static final Formatting
BLACK = from('0'),
DARK_BLUE = from('1'),
DARL_GREEN = from('2'),
CYAN = from('3'),
DARK_RED = from('4'),
PURPLE = from('5'),
ORANGE = from('6'),
GRAY = from('7'),
DARK_GRAY = from('8'),
BLUE = from('9'),
GREEN = from('a'),
AQUA = from('b'),
RED = from('c'),
PINK = from('d'),
YELLOW = from('e'),
WHITE = from('f'),
BOLD = from('l'),
STRIKETHROUGH = from('m'),
UNDERLINE = from('n'),
ITALIC = from('o'),
MAGIC = from('k'),
RESET = from('r'),
EMPTY = from('\0');
public static String stripAll(String value) {
return stripAll(FORMAT_CHAR, value);
}
public static String stripAll(char alternateChar, String value) {
int index = value.indexOf(alternateChar);
int max;
if (index == -1 || index == (max = value.length() - 1)) {
return value;
}
StringBuilder result = new StringBuilder();
int from = 0;
do {
if (isRecognizedChar(value.charAt(index + 1))) {
result.append(value, from, index);
from = index + 2;
} else {
result.append(value, from, from = index + 2);
}
index = value.indexOf(alternateChar, index + 1);
} while (index != -1 && index != max && from <= max);
if (from <= max) {
result.append(value, from, value.length());
}
return result.toString();
}
public static String stripFirst(String value) {
return stripFirst(FORMAT_CHAR, value);
}
public static String stripFirst(char alternateChar, String value) {
int index = value.indexOf(alternateChar);
int max;
if (index == -1 || index == (max = value.length() - 1)) {
return value;
}
StringBuilder result = new StringBuilder(value.length());
int from = 0;
if (isRecognizedChar(value.charAt(index + 1))) {
result.append(value, from, index);
from = index + 2;
} else {
result.append(value, from, from = index + 2);
}
if (from < max) {
result.append(value, from, value.length());
}
return result.toString();
}
public static Formatting from(char c) {
if (isRecognizedChar(c)) {
c = Character.toLowerCase(c);
Formatting res = singleCharInstances.get(c);
if (res == null) {
singleCharInstances.put(c, res = new Formatting(c));
}
return res;
}
return EMPTY;
}
public static Formatting from(String chars) {
return chars.length() == 1 ? from(chars.charAt(0)) : getFormats(chars, '\0');
}
public static Formatting getFormats(String input) {
return getFormats(input, FORMAT_CHAR);
}
public static Formatting getFormats(String input, char formatChar) {
return getFormats(input, 0, input.length(), formatChar);
}
public static Formatting getFormats(String input, int start, int end, char formatChar) {
if ((start < 0) || (start > end) || (end > input.length())) {
throw new IndexOutOfBoundsException("start " + start + ", end " + end + ", input.length() " + input.length());
}
boolean needsFormatChar = formatChar != '\0';
char[] formats = new char[6];
// just make sure it's not the same as formatChar
char previous = (char) (formatChar + 1);
for (int i = start; i < end; i++) {
char c = input.charAt(i);
if (previous == formatChar || !needsFormatChar) {
if (isColourChar(c) || isResetChar(c)) {
formats = new char[6];
formats[0] = Character.toLowerCase(c);
} else if (isFormatChar(c)) {
char format = Character.toLowerCase(c);
for (int j = 0; j < 6; j++) {
if (formats[j] == '\0') {
formats[j] = format;
break;
} else if (formats[j] == format) {
break;
}
}
}
}
previous = c;
}
return formats[1] == '\0' ? from(formats[0]) : new Formatting(formats);
}
public static String translate(String input) {
return translateChars('&', input);
}
public static String translateChars(char alternateChar, String input) {
return translateFormat(alternateChar, FORMAT_CHAR, input);
}
public static String revert(String input) {
return revertChars('&', input);
}
public static String revertChars(char alternateChar, String input) {
return translateFormat(FORMAT_CHAR, alternateChar, input);
}
public static String translateFormat(char fromChar, char toChar, String input) {
if (input == null) {
return null;
}
int n = input.length();
if (n < 2) {
return input;
}
char[] result = null;
char previous = input.charAt(0);
for (int i = 1; i < n; i++) {
char c = input.charAt(i);
if (previous == fromChar && isRecognizedChar(c)) {
if (result == null) {
result = input.toCharArray();
}
result[i - 1] = toChar;
}
previous = c;
}
return result == null ? input : String.valueOf(result);
}
public static void translate(StringBuilder input) {
translateChars('&', input);
}
public static void translateChars(char alternateChar, StringBuilder input) {
translateFormat(alternateChar, FORMAT_CHAR, input);
}
public static void revert(StringBuilder input) {
revertChars('&', input);
}
public static void revertChars(char alternateChar, StringBuilder input) {
translateFormat(FORMAT_CHAR, alternateChar, input);
}
public static void translateFormat(char fromChar, char toChar, StringBuilder input) {
if (input == null) {
return;
}
int n = input.length();
if (n < 2) {
return;
}
char previous = input.charAt(0);
for (int i = 1; i < n; i++) {
char c = input.charAt(i);
if (previous == fromChar && isRecognizedChar(c)) {
input.setCharAt(i - 1, toChar);
}
previous = c;
}
}
private static boolean isRecognizedChar(char c) {
return isColourChar(c) || isFormatChar(c) || isResetChar(c);
}
private static boolean isColourChar(char c) {
return "0123456789abcdefABCDEF".indexOf(c) > -1;
}
private static boolean isResetChar(char c) {
return c == 'r' || c == 'R';
}
private static boolean isFormatChar(char c) {
return "lmnokLMNOK".indexOf(c) > -1;
}
private final String format;
private Formatting(char[] formats) {
StringBuilder format = new StringBuilder(12);
for (char c : formats) {
if (c != '\0') {
format.append(FORMAT_CHAR).append(c);
} else {
break;
}
}
this.format = format.toString();
}
private Formatting(char c) {
this.format = (c != '\0') ? String.valueOf(new char[]{FORMAT_CHAR, c}) : "";
}
@Override
public int length() {
return format.length();
}
@Override
public char charAt(int index) {
return format.charAt(index);
}
@Override
public String subSequence(int start, int end) {
return format.substring(start, end);
}
@Override
public String toString() {
return format;
}
}

View File

@@ -1,5 +1,6 @@
package io.dico.dicore.command.chat;
import io.dico.dicore.Formatting;
import io.dico.dicore.command.CommandException;
import io.dico.dicore.command.EMessageType;
import io.dico.dicore.command.ExecutionContext;

View File

@@ -4,7 +4,7 @@ import io.dico.dicore.command.EMessageType;
import io.dico.dicore.command.ExecutionContext;
import io.dico.dicore.command.ICommandAddress;
import io.dico.dicore.command.ModifiableCommandAddress;
import io.dico.dicore.command.chat.Formatting;
import io.dico.dicore.Formatting;
import io.dico.dicore.command.chat.IChatController;
import io.dico.dicore.command.chat.help.IPageBorder;
import io.dico.dicore.command.chat.help.IPageLayout;

View File

@@ -4,7 +4,7 @@ import io.dico.dicore.command.Command;
import io.dico.dicore.command.EMessageType;
import io.dico.dicore.command.ExecutionContext;
import io.dico.dicore.command.ICommandAddress;
import io.dico.dicore.command.chat.Formatting;
import io.dico.dicore.Formatting;
import io.dico.dicore.command.chat.help.IHelpComponent;
import io.dico.dicore.command.chat.help.IHelpTopic;
import io.dico.dicore.command.chat.help.SimpleHelpComponent;

View File

@@ -3,7 +3,7 @@ package io.dico.dicore.command.chat.help.defaults;
import io.dico.dicore.command.EMessageType;
import io.dico.dicore.command.ExecutionContext;
import io.dico.dicore.command.ICommandAddress;
import io.dico.dicore.command.chat.Formatting;
import io.dico.dicore.Formatting;
import io.dico.dicore.command.chat.help.IHelpComponent;
import io.dico.dicore.command.chat.help.IHelpTopic;
import io.dico.dicore.command.chat.help.SimpleHelpComponent;

View File

@@ -4,7 +4,7 @@ import io.dico.dicore.command.Command;
import io.dico.dicore.command.EMessageType;
import io.dico.dicore.command.ExecutionContext;
import io.dico.dicore.command.ICommandAddress;
import io.dico.dicore.command.chat.Formatting;
import io.dico.dicore.Formatting;
import io.dico.dicore.command.chat.help.IHelpComponent;
import io.dico.dicore.command.chat.help.IHelpTopic;
import io.dico.dicore.command.chat.help.SimpleHelpComponent;

View File

@@ -105,7 +105,7 @@ public class ContextParser {
requireInput = m_curParamIndex <= m_requiredIndex;
} else if (m_buffer.hasNext()) {
throw new CommandException("Too many arguments");
throw new CommandException("Too many arguments for /" + m_context.getAddress().getAddress());
} else {
m_done = true;

View File

@@ -6,7 +6,8 @@ import io.dico.dicore.command.IContextFilter;
import org.bukkit.command.CommandSender;
public class DefaultGroupCommand extends PredefinedCommand<DefaultGroupCommand> {
private static final DefaultGroupCommand instance = new DefaultGroupCommand(false);
private static final DefaultGroupCommand instance;
private static final IContextFilter noArgumentFilter;
public static DefaultGroupCommand getInstance() {
return instance;
@@ -14,6 +15,7 @@ public class DefaultGroupCommand extends PredefinedCommand<DefaultGroupCommand>
private DefaultGroupCommand(boolean modifiable) {
addContextFilter(IContextFilter.INHERIT_PERMISSIONS);
addContextFilter(noArgumentFilter);
this.modifiable = modifiable;
}
@@ -32,4 +34,23 @@ public class DefaultGroupCommand extends PredefinedCommand<DefaultGroupCommand>
return null;
}
static {
noArgumentFilter = new IContextFilter() {
@Override
public void filterContext(ExecutionContext context) throws CommandException {
if (context.getProcessedBuffer().hasNext()) {
throw new CommandException("No such command: /" + context.getAddress().getAddress()
+ " " + context.getProcessedBuffer().next());
}
}
@Override
public Priority getPriority() {
return Priority.EARLY;
}
};
instance = new DefaultGroupCommand(false);
}
}

View File

@@ -9,12 +9,10 @@
package io.dico.dicore;
import gnu.trove.map.TCharObjectMap;
import gnu.trove.map.hash.TCharObjectHashMap;
public final class Formatting implements CharSequence {
public static final char FORMAT_CHAR = '\u00a7';
private static final TCharObjectMap<Formatting> singleCharInstances = new TCharObjectHashMap<>(16, .5F, '\0');
private static final String CACHED_CHARS = "0123456789abcdefklmnor";
private static final Formatting[] singleCharInstances = new Formatting[CACHED_CHARS.length()];
public static final Formatting
BLACK = from('0'),
@@ -100,9 +98,12 @@ public final class Formatting implements CharSequence {
public static Formatting from(char c) {
if (isRecognizedChar(c)) {
c = Character.toLowerCase(c);
Formatting res = singleCharInstances.get(c);
int index = CACHED_CHARS.indexOf(c);
if (index == -1) return EMPTY;
Formatting res = singleCharInstances[index];
if (res == null) {
singleCharInstances.put(c, res = new Formatting(c));
singleCharInstances[index] = res = new Formatting(c);
}
return res;
}
@@ -229,13 +230,13 @@ public final class Formatting implements CharSequence {
previous = c;
}
}
private static boolean isRecognizedChar(char c) {
return isColourChar(c) || isFormatChar(c) || isResetChar(c);
}
private static boolean isColourChar(char c) {
return "0123456789abcdefABCDEF".indexOf(c) > -1;
return "0123456789abcdefABCDEF".indexOf(c) >= 0;
}
private static boolean isResetChar(char c) {
@@ -243,7 +244,7 @@ public final class Formatting implements CharSequence {
}
private static boolean isFormatChar(char c) {
return "lmnokLMNOK".indexOf(c) > -1;
return "klmnoKLMNO".indexOf(c) >= 0;
}
private final String format;

View File

@@ -1,6 +1,6 @@
package io.dico.parcels2
import io.dico.parcels2.util.math.ext.ceilDiv
import io.dico.parcels2.util.math.ceilDiv
import io.dico.parcels2.util.ext.getMaterialsWithWoodTypePrefix
import org.bukkit.Material
import java.util.EnumMap

View File

@@ -3,7 +3,7 @@ package io.dico.parcels2
import io.dico.parcels2.options.RuntimeWorldOptions
import io.dico.parcels2.storage.Storage
import io.dico.parcels2.util.math.Vec2i
import io.dico.parcels2.util.math.ext.floor
import io.dico.parcels2.util.math.floor
import org.bukkit.Location
import org.bukkit.World
import org.bukkit.block.Block

View File

@@ -2,7 +2,7 @@ package io.dico.parcels2.blockvisitor
import io.dico.parcels2.ParcelsPlugin
import io.dico.parcels2.logger
import io.dico.parcels2.util.math.ext.clampMin
import io.dico.parcels2.util.math.clampMin
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart.LAZY

View File

@@ -3,7 +3,7 @@ package io.dico.parcels2.blockvisitor
import io.dico.parcels2.util.math.Dimension
import io.dico.parcels2.util.math.Region
import io.dico.parcels2.util.math.Vec3i
import io.dico.parcels2.util.math.ext.clampMax
import io.dico.parcels2.util.math.clampMax
private typealias Scope = SequenceScope<Vec3i>

View File

@@ -88,7 +88,7 @@ private fun generateCommands(address: ICommandAddress, vararg names: String) {
while (addresses.isNotEmpty()) {
val cur = addresses.poll()
addresses.addAll(cur.children.values.distinct())
cur.childrenMainKeys.mapTo(addresses) { cur.getChild(it) }
if (cur.hasCommand()) {
ReflectiveRegistration.generateCommands(cur, names)
}

View File

@@ -17,7 +17,7 @@ import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.PREFER_OWNED_F
import io.dico.parcels2.command.ParcelTarget.TargetKind.Companion.REAL
import io.dico.parcels2.storage.Storage
import io.dico.parcels2.util.math.Vec2i
import io.dico.parcels2.util.math.ext.floor
import io.dico.parcels2.util.math.floor
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player

View File

@@ -6,8 +6,8 @@ import io.dico.parcels2.options.DefaultGeneratorOptions
import io.dico.parcels2.util.math.Region
import io.dico.parcels2.util.math.Vec2i
import io.dico.parcels2.util.math.Vec3i
import io.dico.parcels2.util.math.ext.even
import io.dico.parcels2.util.math.ext.umod
import io.dico.parcels2.util.math.even
import io.dico.parcels2.util.math.umod
import io.dico.parcels2.util.math.get
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart.UNDISPATCHED

View File

@@ -10,8 +10,8 @@ import io.dico.parcels2.util.ext.*
import io.dico.parcels2.util.math.Dimension
import io.dico.parcels2.util.math.Vec3d
import io.dico.parcels2.util.math.Vec3i
import io.dico.parcels2.util.math.ext.clampMax
import io.dico.parcels2.util.math.ext.clampMin
import io.dico.parcels2.util.math.clampMax
import io.dico.parcels2.util.math.clampMin
import org.bukkit.Location
import org.bukkit.Material.*
import org.bukkit.World

View File

@@ -6,7 +6,7 @@ import com.zaxxer.hikari.HikariDataSource
import io.dico.parcels2.*
import io.dico.parcels2.PlayerProfile.Star.name
import io.dico.parcels2.storage.*
import io.dico.parcels2.util.math.ext.clampMax
import io.dico.parcels2.util.math.clampMax
import io.dico.parcels2.util.ext.synchronized
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.ArrayChannel

View File

@@ -36,7 +36,7 @@ fun MainThreadDispatcher(plugin: Plugin): MainThreadDispatcher {
with (continuation) { resumeUndispatched(Unit) }
}
val millis = TimeUnit.MILLISECONDS.convert(time, unit)
val millis = unit.toMillis(time)
plugin.server.scheduler.runTaskLater(plugin, task, (millis + 25) / 50 - 1)
}
}

View File

@@ -2,10 +2,7 @@ package io.dico.parcels2.util.ext
import io.dico.dicore.Formatting
import io.dico.parcels2.logger
import org.bukkit.Bukkit
import org.bukkit.OfflinePlayer
import java.io.File
import java.util.UUID
fun File.tryCreate(): Boolean {
if (exists()) {

View File

@@ -1,4 +1,4 @@
package io.dico.parcels2.util.math.ext
package io.dico.parcels2.util.math
fun Double.floor(): Int {
val down = toInt()

View File

@@ -1,6 +1,5 @@
package io.dico.parcels2.util.math
import io.dico.parcels2.util.math.ext.floor
import org.bukkit.Location
import kotlin.math.sqrt

View File

@@ -1,6 +1,5 @@
package io.dico.parcels2.util.math
import io.dico.parcels2.util.math.ext.clampMax
import org.bukkit.Location
import org.bukkit.World
import org.bukkit.block.Block