package net.minecraft.command.type.custom; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; import java.util.regex.Matcher; import net.minecraft.command.ParsingUtilities; import net.minecraft.command.SyntaxErrorException; import net.minecraft.command.arg.ArgWrapper; import net.minecraft.command.collections.TypeIDs; import net.minecraft.command.completion.TCDSet; import net.minecraft.command.completion.TabCompletionData; import net.minecraft.command.descriptors.CommandDescriptor; import net.minecraft.command.descriptors.ICommandDescriptor; import net.minecraft.command.parser.CompletionParser; import net.minecraft.command.parser.CompletionParser.CompletionData; import net.minecraft.command.parser.Context; import net.minecraft.command.parser.Parser; import net.minecraft.command.type.CTypeParse; import net.minecraft.command.type.base.ExCustomCompletable; import net.minecraft.command.type.custom.command.ParserCommand; import net.minecraft.command.type.metadata.MetaEntry; import net.minecraft.command.type.metadata.MetaEntry.PrimitiveHint; public class TypeCommandPath extends CTypeParse<List<String>> { public static final TypeCommandPath parser = new TypeCommandPath(); private TypeCommandPath() { } @Override public ArgWrapper<List<String>> iParse(final Parser parser, final Context parserData) throws SyntaxErrorException { final List<String> data = new ArrayList<>(); while (ITypeCommandPath.parser.parse(parser, data) != null && !parser.endReached()) { } return TypeIDs.StringList.wrap(data); } /** * @param path * Must NOT be empty */ private static final ICommandDescriptor<?> descFromPath(final List<String> path) { final ListIterator<String> it = path.listIterator(); ICommandDescriptor<?> currDesc = CommandDescriptor.getDescriptor(it.next()); if (currDesc == null) return null; while (it.hasNext()) { final String next = it.next(); ICommandDescriptor<?> newDesc = currDesc.getSubDescriptor(next); if (newDesc == null) { it.previous(); newDesc = currDesc.getSubDescriptor(""); if (newDesc == null) return null; } currDesc = newDesc; } return currDesc; } private static final MetaEntry<PrimitiveHint, Void> hint = new MetaEntry<PrimitiveHint, Void>(CompletionParser.hintID) { @Override public PrimitiveHint get(final Parser parser, final Void parserData) { final Matcher wm = parser.getMatcher(ParsingUtilities.whitespaceMatcher); parser.find(wm); return wm.group().length() + parser.getIndex() == parser.len ? CompletionParser.propose : null; } }; private static class ITypeCommandPath extends ExCustomCompletable<String, List<String>> { private static final ITypeCommandPath parser = new ITypeCommandPath(); @Override public String iParse(final Parser parser, final List<String> parserData) throws SyntaxErrorException { final Matcher m = parser.getMatcher(ParsingUtilities.keyMatcher); if (!parser.findInc(m)) { parser.supplyHint(hint); return null; } final String key = m.group(1); parserData.add(key); return key; } @Override public void complete(final TCDSet tcDataSet, final Parser parser, final int startIndex, final CompletionData cData, final List<String> parserData) { final List<String> path = startIndex == parser.getIndex() ? parserData : parserData.subList(0, parserData.size() - 1); if (path.isEmpty()) { ParserCommand.nameCompleter.complete(tcDataSet, parser, startIndex, cData); return; } ICommandDescriptor<?> desc = descFromPath(path); //TODO: Permission? while (desc != null) { TabCompletionData.addToSet(tcDataSet, startIndex, cData, desc.getKeywordCompletions()); desc = desc.getSubDescriptor(""); } } } }