mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-05 12:36:40 +00:00
Various command (use es6 if java9 + nashorn)
This commit is contained in:
@ -12,62 +12,10 @@ import com.boydti.fawe.util.chat.ChatManager;
|
||||
import com.boydti.fawe.util.chat.PlainChatManager;
|
||||
import com.boydti.fawe.util.cui.CUI;
|
||||
import com.boydti.fawe.util.metrics.BStats;
|
||||
import com.boydti.fawe.wrappers.FakePlayer;
|
||||
import com.sk89q.jnbt.*;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.command.*;
|
||||
import com.sk89q.worldedit.command.composition.SelectionCommand;
|
||||
import com.sk89q.worldedit.command.tool.*;
|
||||
import com.sk89q.worldedit.command.tool.brush.GravityBrush;
|
||||
import com.sk89q.worldedit.event.extent.EditSessionEvent;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultMaskParser;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultTransformParser;
|
||||
import com.sk89q.worldedit.extension.factory.HashTagPatternParser;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.CommandManager;
|
||||
import com.sk89q.worldedit.extension.platform.PlatformManager;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.MaskingExtent;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.SchematicReader;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBagExtent;
|
||||
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
||||
import com.sk89q.worldedit.function.CombinedRegionFunction;
|
||||
import com.sk89q.worldedit.function.block.BlockReplace;
|
||||
import com.sk89q.worldedit.function.block.ExtentBlockCopy;
|
||||
import com.sk89q.worldedit.function.entity.ExtentEntityCopy;
|
||||
import com.sk89q.worldedit.function.mask.*;
|
||||
import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.pattern.*;
|
||||
import com.sk89q.worldedit.function.visitor.*;
|
||||
import com.sk89q.worldedit.internal.command.WorldEditBinding;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.*;
|
||||
import com.sk89q.worldedit.math.convolution.HeightMap;
|
||||
import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.CylinderRegion;
|
||||
import com.sk89q.worldedit.regions.EllipsoidRegion;
|
||||
import com.sk89q.worldedit.regions.selector.*;
|
||||
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.session.PasteBuilder;
|
||||
import com.sk89q.worldedit.session.SessionManager;
|
||||
import com.sk89q.worldedit.session.request.Request;
|
||||
import com.sk89q.worldedit.util.command.SimpleCommandMapping;
|
||||
import com.sk89q.worldedit.util.command.SimpleDispatcher;
|
||||
import com.sk89q.worldedit.util.command.fluent.DispatcherNode;
|
||||
import com.sk89q.worldedit.util.command.parametric.*;
|
||||
import com.sk89q.worldedit.util.formatting.Fragment;
|
||||
import com.sk89q.worldedit.util.formatting.component.CommandListBox;
|
||||
import com.sk89q.worldedit.util.formatting.component.CommandUsageBox;
|
||||
import com.sk89q.worldedit.util.formatting.component.MessageBox;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.management.InstanceAlreadyExistsException;
|
||||
@ -418,6 +366,8 @@ public class Fawe {
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "tr/message.yml", null);
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "es/message.yml", null);
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "es/commands.yml", null);
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "nl/message.yml", null);
|
||||
MainUtil.copyFile(MainUtil.getJarFile(), "fr/message.yml", null);
|
||||
// Setting up config.yml
|
||||
File file = new File(this.IMP.getDirectory(), "config.yml");
|
||||
Settings.IMP.PLATFORM = IMP.getPlatform().replace("\"", "");
|
||||
|
@ -135,18 +135,18 @@ public class AnvilCommands {
|
||||
}
|
||||
}
|
||||
|
||||
// @Command(
|
||||
// aliases = {"replaceall", "rea", "repall"},
|
||||
// usage = "<folder> [from-block] <to-block>",
|
||||
// desc = "Replace all blocks in the selection with another",
|
||||
// help = "Replace all blocks in the selection with another\n" +
|
||||
// "The -d flag disabled wildcard data matching\n",
|
||||
// flags = "df",
|
||||
// min = 2,
|
||||
// max = 4
|
||||
// )
|
||||
// @CommandPermissions("worldedit.anvil.replaceall")
|
||||
// public void replaceAll(Player player, String folder, @Optional String from, String to, @Switch('d') boolean useData) throws WorldEditException {
|
||||
@Command(
|
||||
aliases = {"replaceall", "rea", "repall"},
|
||||
usage = "<folder> [from-block] <to-block>",
|
||||
desc = "Replace all blocks in the selection with another",
|
||||
help = "Replace all blocks in the selection with another\n" +
|
||||
"The -d flag disabled wildcard data matching\n",
|
||||
flags = "df",
|
||||
min = 2,
|
||||
max = 4
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.replaceall")
|
||||
public void replaceAll(Player player, String folder, @Optional String from, String to, @Switch('d') boolean useData) throws WorldEditException {
|
||||
// final FaweBlockMatcher matchFrom;
|
||||
// if (from == null) {
|
||||
// matchFrom = FaweBlockMatcher.NOT_AIR;
|
||||
@ -160,7 +160,7 @@ public class AnvilCommands {
|
||||
// ReplaceSimpleFilter filter = new ReplaceSimpleFilter(matchFrom, matchTo);
|
||||
// ReplaceSimpleFilter result = runWithWorld(player, folder, filter, true);
|
||||
// if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
// }
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"remapall"},
|
||||
@ -333,16 +333,16 @@ public class AnvilCommands {
|
||||
if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
|
||||
// @Command(
|
||||
// aliases = {"replaceallpattern", "reap", "repallpat"},
|
||||
// usage = "<folder> [from-block] <to-pattern>",
|
||||
// desc = "Replace all blocks in the selection with another",
|
||||
// flags = "dm",
|
||||
// min = 2,
|
||||
// max = 4
|
||||
// )
|
||||
// @CommandPermissions("worldedit.anvil.replaceall")
|
||||
// public void replaceAllPattern(Player player, String folder, @Optional String from, final Pattern to, @Switch('d') boolean useData, @Switch('m') boolean useMap) throws WorldEditException {
|
||||
@Command(
|
||||
aliases = {"replaceallpattern", "reap", "repallpat"},
|
||||
usage = "<folder> [from-block] <to-pattern>",
|
||||
desc = "Replace all blocks in the selection with another",
|
||||
flags = "dm",
|
||||
min = 2,
|
||||
max = 4
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.replaceall")
|
||||
public void replaceAllPattern(Player player, String folder, @Optional String from, final Pattern to, @Switch('d') boolean useData, @Switch('m') boolean useMap) throws WorldEditException {
|
||||
// MCAFilterCounter filter;
|
||||
// if (useMap) {
|
||||
// if (to instanceof RandomPattern) {
|
||||
@ -363,18 +363,18 @@ public class AnvilCommands {
|
||||
// }
|
||||
// MCAFilterCounter result = runWithWorld(player, folder, filter, true);
|
||||
// if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
// }
|
||||
}
|
||||
//
|
||||
// @Command(
|
||||
// aliases = {"countall"},
|
||||
// usage = "<folder> [hasSky] <id>",
|
||||
// desc = "Count all blocks in a world",
|
||||
// flags = "d",
|
||||
// min = 2,
|
||||
// max = 3
|
||||
// )
|
||||
// @CommandPermissions("worldedit.anvil.countall")
|
||||
// public void countAll(Player player, EditSession editSession, String folder, String arg, @Switch('d') boolean useData) throws WorldEditException {
|
||||
@Command(
|
||||
aliases = {"countall"},
|
||||
usage = "<folder> [hasSky] <id>",
|
||||
desc = "Count all blocks in a world",
|
||||
flags = "d",
|
||||
min = 2,
|
||||
max = 3
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.countall")
|
||||
public void countAll(Player player, EditSession editSession, String folder, String arg, @Switch('d') boolean useData) throws WorldEditException {
|
||||
// Set<BaseBlock> searchBlocks = worldEdit.getBlocks(player, arg, true);
|
||||
// MCAFilterCounter filter;
|
||||
// if (useData || arg.contains(":")) { // Optimize for both cases
|
||||
@ -388,7 +388,7 @@ public class AnvilCommands {
|
||||
// }
|
||||
// MCAFilterCounter result = runWithWorld(player, folder, filter, true);
|
||||
// if (result != null) player.print(BBC.getPrefix() + BBC.SELECTION_COUNT.format(result.getTotal()));
|
||||
// }
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"clear", "unset"},
|
||||
@ -440,16 +440,16 @@ public class AnvilCommands {
|
||||
if (result != null) player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
}
|
||||
|
||||
// @Command(
|
||||
// aliases = {"count"},
|
||||
// usage = "<ids>",
|
||||
// desc = "Count blocks in a selection",
|
||||
// flags = "d",
|
||||
// min = 1,
|
||||
// max = 2
|
||||
// )
|
||||
// @CommandPermissions("worldedit.anvil.count")
|
||||
// public void count(Player player, EditSession editSession, @Selection Region selection, String arg, @Switch('d') boolean useData) throws WorldEditException {
|
||||
@Command(
|
||||
aliases = {"count"},
|
||||
usage = "<ids>",
|
||||
desc = "Count blocks in a selection",
|
||||
flags = "d",
|
||||
min = 1,
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.count")
|
||||
public void count(Player player, EditSession editSession, @Selection Region selection, String arg, @Switch('d') boolean useData) throws WorldEditException {
|
||||
// Set<BaseBlock> searchBlocks = worldEdit.getBlocks(player, arg, true);
|
||||
// MCAFilterCounter filter;
|
||||
// if (useData || arg.contains(":")) { // Optimize for both cases
|
||||
@ -463,14 +463,14 @@ public class AnvilCommands {
|
||||
// }
|
||||
// MCAFilterCounter result = runWithSelection(player, editSession, selection, filter);
|
||||
// if (result != null) player.print(BBC.getPrefix() + BBC.SELECTION_COUNT.format(result.getTotal()));
|
||||
// }
|
||||
}
|
||||
//
|
||||
// @Command(
|
||||
// aliases = {"distr"},
|
||||
// desc = "Replace all blocks in the selection with another"
|
||||
// )
|
||||
// @CommandPermissions("worldedit.anvil.distr")
|
||||
// public void distr(Player player, EditSession editSession, @Selection Region selection, @Switch('d') boolean useData) throws WorldEditException {
|
||||
@Command(
|
||||
aliases = {"distr"},
|
||||
desc = "Replace all blocks in the selection with another"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.distr")
|
||||
public void distr(Player player, EditSession editSession, @Selection Region selection, @Switch('d') boolean useData) throws WorldEditException {
|
||||
// long total = 0;
|
||||
// long[] count;
|
||||
// MCAFilter<long[]> counts;
|
||||
@ -540,15 +540,15 @@ public class AnvilCommands {
|
||||
// player.print(BBC.getPrefix() + str);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
//
|
||||
// @Command(
|
||||
// aliases = {"replace", "r"},
|
||||
// usage = "[from-block] <to-block>",
|
||||
// desc = "Replace all blocks in the selection with another"
|
||||
// )
|
||||
// @CommandPermissions("worldedit.anvil.replace")
|
||||
// public void replace(Player player, EditSession editSession, @Selection Region selection, @Optional String from, String to, @Switch('d') boolean useData) throws WorldEditException {
|
||||
@Command(
|
||||
aliases = {"replace", "r"},
|
||||
usage = "[from-block] <to-block>",
|
||||
desc = "Replace all blocks in the selection with another"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.replace")
|
||||
public void replace(Player player, EditSession editSession, @Selection Region selection, @Optional String from, String to, @Switch('d') boolean useData) throws WorldEditException {
|
||||
// final FaweBlockMatcher matchFrom;
|
||||
// if (from == null) {
|
||||
// matchFrom = FaweBlockMatcher.NOT_AIR;
|
||||
@ -561,16 +561,16 @@ public class AnvilCommands {
|
||||
// if (result != null) {
|
||||
// player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
//
|
||||
// @Command(
|
||||
// aliases = {"replacepattern", "preplace", "rp"},
|
||||
// usage = "[from-mask] <to-pattern>",
|
||||
// desc = "Replace all blocks in the selection with a pattern"
|
||||
// )
|
||||
// @CommandPermissions("worldedit.anvil.replace")
|
||||
// // Player player, String folder, @Optional String from, final Pattern to, @Switch('d') boolean useData, @Switch('m') boolean useMap
|
||||
// public void replacePattern(Player player, EditSession editSession, @Selection Region selection, @Optional String from, final Pattern to, @Switch('d') boolean useData, @Switch('m') boolean useMap) throws WorldEditException {
|
||||
@Command(
|
||||
aliases = {"replacepattern", "preplace", "rp"},
|
||||
usage = "[from-mask] <to-pattern>",
|
||||
desc = "Replace all blocks in the selection with a pattern"
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.replace")
|
||||
// Player player, String folder, @Optional String from, final Pattern to, @Switch('d') boolean useData, @Switch('m') boolean useMap
|
||||
public void replacePattern(Player player, EditSession editSession, @Selection Region selection, @Optional String from, final Pattern to, @Switch('d') boolean useData, @Switch('m') boolean useMap) throws WorldEditException {
|
||||
// MCAFilterCounter filter;
|
||||
// if (useMap) {
|
||||
// if (to instanceof RandomPattern) {
|
||||
@ -593,7 +593,7 @@ public class AnvilCommands {
|
||||
// if (result != null) {
|
||||
// player.print(BBC.getPrefix() + BBC.VISITOR_BLOCK.format(result.getTotal()));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"set"},
|
||||
@ -651,17 +651,17 @@ public class AnvilCommands {
|
||||
BBC.COMMAND_COPY.send(player, selection.getArea());
|
||||
}
|
||||
|
||||
// @Command(
|
||||
// aliases = {"paste"},
|
||||
// desc = "Paste chunks from your anvil clipboard",
|
||||
// help =
|
||||
// "Paste the chunks from your anvil clipboard.\n" +
|
||||
// "The -c flag will align the paste to the chunks.",
|
||||
// flags = "c"
|
||||
//
|
||||
// )
|
||||
// @CommandPermissions("worldedit.anvil.pastechunks")
|
||||
// public void paste(Player player, LocalSession session, EditSession editSession, @Switch('c') boolean alignChunk) throws WorldEditException, IOException {
|
||||
@Command(
|
||||
aliases = {"paste"},
|
||||
desc = "Paste chunks from your anvil clipboard",
|
||||
help =
|
||||
"Paste the chunks from your anvil clipboard.\n" +
|
||||
"The -c flag will align the paste to the chunks.",
|
||||
flags = "c"
|
||||
|
||||
)
|
||||
@CommandPermissions("worldedit.anvil.pastechunks")
|
||||
public void paste(Player player, LocalSession session, EditSession editSession, @Switch('c') boolean alignChunk) throws WorldEditException, IOException {
|
||||
// FawePlayer fp = FawePlayer.wrap(player);
|
||||
// MCAClipboard clipboard = fp.getMeta(FawePlayer.METADATA_KEYS.ANVIL_CLIPBOARD);
|
||||
// if (clipboard == null) {
|
||||
@ -689,5 +689,5 @@ public class AnvilCommands {
|
||||
// } catch (IOException e) { throw new RuntimeException(e); }
|
||||
// });
|
||||
// BBC.COMMAND_PASTE.send(player, player.getPosition().toBlockVector());
|
||||
// }
|
||||
}
|
||||
}
|
@ -25,21 +25,21 @@ public abstract class FaweParser<T> extends InputParser<T> {
|
||||
|
||||
public abstract Dispatcher getDispatcher();
|
||||
|
||||
public List<String> suggestRemaining(String input, String... expected) throws InputParseException {
|
||||
List<String> remainder = StringMan.split(input, ':');
|
||||
int len = remainder.size();
|
||||
if (len != expected.length - 1) {
|
||||
if (len <= expected.length - 1 && len != 0) {
|
||||
if (remainder.get(len - 1).endsWith(":")) {
|
||||
throw new SuggestInputParseException(null, StringMan.join(expected, ":"));
|
||||
}
|
||||
throw new SuggestInputParseException(null, expected[0] + ":" + input + ":" + StringMan.join(Arrays.copyOfRange(expected, len + 1, 3), ":"));
|
||||
} else {
|
||||
throw new SuggestInputParseException(null, StringMan.join(expected, ":"));
|
||||
}
|
||||
}
|
||||
return remainder;
|
||||
}
|
||||
// public List<String> suggestRemaining(String input, String... expected) throws InputParseException {
|
||||
// List<String> remainder = StringMan.split(input, ':');
|
||||
// int len = remainder.size();
|
||||
// if (len != expected.length - 1) {
|
||||
// if (len <= expected.length - 1 && len != 0) {
|
||||
// if (remainder.get(len - 1).endsWith(":")) {
|
||||
// throw new SuggestInputParseException(null, StringMan.join(expected, ":"));
|
||||
// }
|
||||
// throw new SuggestInputParseException(null, expected[0] + ":" + input + ":" + StringMan.join(Arrays.copyOfRange(expected, len + 1, 3), ":"));
|
||||
// } else {
|
||||
// throw new SuggestInputParseException(null, StringMan.join(expected, ":"));
|
||||
// }
|
||||
// }
|
||||
// return remainder;
|
||||
// }
|
||||
|
||||
protected static class ParseEntry {
|
||||
public boolean and;
|
||||
@ -58,7 +58,7 @@ public abstract class FaweParser<T> extends InputParser<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public List<Map.Entry<ParseEntry, List<String>>> parse(String toParse) throws InputParseException {
|
||||
public static List<Map.Entry<ParseEntry, List<String>>> parse(String toParse) throws InputParseException {
|
||||
List<Map.Entry<ParseEntry, List<String>>> keys = new ArrayList<>();
|
||||
List<String> inputs = new ArrayList<>();
|
||||
List<Boolean> and = new ArrayList<>();
|
||||
@ -83,8 +83,11 @@ public abstract class FaweParser<T> extends InputParser<T> {
|
||||
int next = StringMan.findMatchingBracket(toParse, i);
|
||||
if (next != -1) {
|
||||
i = next;
|
||||
continue outer;
|
||||
} else {
|
||||
toParse += "]";
|
||||
i = toParse.length();
|
||||
}
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -93,7 +96,7 @@ public abstract class FaweParser<T> extends InputParser<T> {
|
||||
String full = inputs.get(i);
|
||||
String command = full;
|
||||
List<String> args = new ArrayList<>();
|
||||
while (command.charAt(command.length() - 1) == ']') {
|
||||
while (!command.isEmpty() && command.charAt(command.length() - 1) == ']') {
|
||||
int startPos = StringMan.findMatchingBracket(command, command.length() - 1);
|
||||
if (startPos == -1) break;
|
||||
String arg = command.substring(startPos + 1, command.length() - 1);
|
||||
|
@ -1,9 +1,16 @@
|
||||
package com.boydti.fawe.command;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultMaskParser;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParameterData;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class MaskBinding extends FaweBinding {
|
||||
private final WorldEdit worldEdit;
|
||||
@ -15,25 +22,9 @@ public class MaskBinding extends FaweBinding {
|
||||
|
||||
@Override
|
||||
public List<String> getSuggestions(ParameterData parameter, String prefix) {
|
||||
// int index = prefix.lastIndexOf(",");
|
||||
// String start = index != -1 ? prefix.substring(0, index) : "";
|
||||
// String current = index != -1 ? prefix.substring(index) : prefix;
|
||||
// if (current.isEmpty()) {
|
||||
// return MainUtil.prepend(start, Arrays.asList(DefaultMaskParser.ALL_MASKS));
|
||||
// }
|
||||
// if (current.startsWith("#") || current.startsWith("=")) {
|
||||
// return new ArrayList<>();
|
||||
// }
|
||||
// if (StringMan.isAlphanumeric(current.charAt(0) + "")) {
|
||||
// String[] split2 = current.split(":");
|
||||
// if (split2.length == 2 || current.endsWith(":")) {
|
||||
// start = (start.isEmpty() ? split2[0] : start + " " + split2[0]) + ":";
|
||||
// current = split2.length == 2 ? split2[1] : "";
|
||||
// return MainUtil.prepend(start, MainUtil.filter(current, BundledBlockData.getInstance().getBlockStates(split2[0])));
|
||||
// }
|
||||
// List<String> blocks = BundledBlockData.getInstance().getBlockNames(split2[0]);
|
||||
// return MainUtil.prepend(start, blocks);
|
||||
// }
|
||||
if (prefix.isEmpty()) {
|
||||
return Stream.concat(Stream.of("#"), BlockTypes.getNameSpaces().stream().map(n -> n + ":")).collect(Collectors.toList());
|
||||
}
|
||||
return super.getSuggestions(parameter, prefix);
|
||||
}
|
||||
}
|
@ -2,9 +2,13 @@ package com.boydti.fawe.command;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParameterData;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class PatternBinding extends FaweBinding {
|
||||
private final WorldEdit worldEdit;
|
||||
@ -16,32 +20,9 @@ public class PatternBinding extends FaweBinding {
|
||||
|
||||
@Override
|
||||
public List<String> getSuggestions(ParameterData parameter, String prefix) {
|
||||
if (prefix.isEmpty()) {
|
||||
return Stream.concat(Stream.of("#"), BlockTypes.getNameSpaces().stream()).collect(Collectors.toList());
|
||||
}
|
||||
return super.getSuggestions(parameter, prefix);
|
||||
// int index = prefix.lastIndexOf(",|%");
|
||||
// String start = index != -1 ? prefix.substring(0, index) : "";
|
||||
// String current = index != -1 ? prefix.substring(index) : prefix;
|
||||
// if (current.isEmpty()) {
|
||||
// return MainUtil.prepend(start, Arrays.asList(HashTagPatternParser.ALL_PATTERNS));
|
||||
// }
|
||||
// if (current.startsWith("#") || current.startsWith("=")) {
|
||||
// return new ArrayList<>();
|
||||
// }
|
||||
// if ("hand".startsWith(prefix)) {
|
||||
// return MainUtil.prepend(start, Arrays.asList("hand"));
|
||||
// }
|
||||
// if ("pos1".startsWith(prefix)) {
|
||||
// return MainUtil.prepend(start, Arrays.asList("pos1"));
|
||||
// }
|
||||
// if (current.contains("|")) {
|
||||
// return new ArrayList<>();
|
||||
// }
|
||||
// String[] split2 = current.split(":");
|
||||
// if (split2.length == 2 || current.endsWith(":")) {
|
||||
// start = (start.isEmpty() ? split2[0] : start + " " + split2[0]) + ":";
|
||||
// current = split2.length == 2 ? split2[1] : "";
|
||||
// return MainUtil.prepend(start, MainUtil.filter(current, BundledBlockData.getInstance().getBlockStates(split2[0])));
|
||||
// }
|
||||
// List<String> blocks = BundledBlockData.getInstance().getBlockNames(split2[0]);
|
||||
// return MainUtil.prepend(start, blocks);
|
||||
}
|
||||
}
|
||||
|
@ -2,87 +2,73 @@ package com.boydti.fawe.command;
|
||||
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class SuggestInputParseException extends InputParseException {
|
||||
|
||||
private final String message;
|
||||
private final InputParseException cause;
|
||||
private final Supplier<List<String>> getSuggestions;
|
||||
private String prefix;
|
||||
private ArrayList<String> suggestions = new ArrayList<>();
|
||||
|
||||
public SuggestInputParseException(String input, Collection<String> inputs) {
|
||||
super("");
|
||||
this.message = "Suggested input: " + StringMan.join(suggestions = getSuggestions(input, inputs), ", ");
|
||||
this.prefix = "";
|
||||
public SuggestInputParseException(String msg, String prefix, Supplier<List<String>> getSuggestions) {
|
||||
this(new InputParseException(msg), prefix, getSuggestions);
|
||||
}
|
||||
|
||||
public SuggestInputParseException(String input, String... inputs) {
|
||||
super("");
|
||||
this.message = "Suggested input: " + StringMan.join(suggestions = getSuggestions(input, inputs), ", ");
|
||||
this.prefix = "";
|
||||
public static SuggestInputParseException of(Throwable other, String prefix, Supplier<List<String>> getSuggestions) {
|
||||
if (other instanceof InputParseException) return of((InputParseException) other, prefix, getSuggestions);
|
||||
return of(new InputParseException(other.getMessage()), prefix, getSuggestions);
|
||||
}
|
||||
|
||||
public static SuggestInputParseException of(InputParseException other, String prefix, Supplier<List<String>> getSuggestions) {
|
||||
if (other instanceof SuggestInputParseException) return (SuggestInputParseException) other;
|
||||
return new SuggestInputParseException(other, prefix, getSuggestions);
|
||||
}
|
||||
|
||||
public SuggestInputParseException(InputParseException other, String prefix, Supplier<List<String>> getSuggestions) {
|
||||
super(other.getMessage());
|
||||
checkNotNull(getSuggestions);
|
||||
checkNotNull(other);
|
||||
this.cause = other;
|
||||
this.getSuggestions = getSuggestions;
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public static SuggestInputParseException get(InvocationTargetException e) {
|
||||
Throwable t = e;
|
||||
while (t.getCause() != null) {
|
||||
t = t.getCause();
|
||||
if (t instanceof SuggestInputParseException) return (SuggestInputParseException) t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Throwable getCause() {
|
||||
return cause.getCause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
return cause.getMessage();
|
||||
}
|
||||
|
||||
|
||||
public List<String> getSuggestions() {
|
||||
return MainUtil.prepend(prefix, suggestions);
|
||||
return getSuggestions.get();
|
||||
}
|
||||
|
||||
public SuggestInputParseException prepend(String input) {
|
||||
this.prefix = input + prefix;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static SuggestInputParseException get(Throwable e) {
|
||||
if (e instanceof SuggestInputParseException) {
|
||||
return (SuggestInputParseException) e;
|
||||
}
|
||||
Throwable cause = e.getCause();
|
||||
if (cause == null) {
|
||||
return null;
|
||||
}
|
||||
return get(cause);
|
||||
}
|
||||
|
||||
private static ArrayList<String> getSuggestions(String input, Collection<String> inputs) {
|
||||
ArrayList<String> suggestions = new ArrayList<>();
|
||||
if (input != null) {
|
||||
String tmp = input.toLowerCase();
|
||||
for (String s : inputs) {
|
||||
if (s.startsWith(tmp)) {
|
||||
suggestions.add(s);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (suggestions.isEmpty()) {
|
||||
suggestions.addAll(inputs);
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
private static ArrayList<String> getSuggestions(String input, String... inputs) {
|
||||
ArrayList<String> suggestions = new ArrayList<>();
|
||||
if (input != null) {
|
||||
String tmp = input.toLowerCase();
|
||||
for (String s : inputs) {
|
||||
if (s.startsWith(tmp)) {
|
||||
suggestions.add(s);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (suggestions.isEmpty()) {
|
||||
for (String s : inputs) {
|
||||
suggestions.add(s);
|
||||
}
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,8 @@ public class Commands {
|
||||
}
|
||||
}
|
||||
|
||||
public static Command fromArgs(String[] aliases, String usage, String desc, int min, int max, String flags, String help) {
|
||||
public static Command fromArgs(String[] aliases, String usage, String desc, int min, Integer max, String flags, String help) {
|
||||
int finalMax = max == null ? -1 : max;
|
||||
return new Command() {
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
@ -54,7 +55,7 @@ public class Commands {
|
||||
}
|
||||
@Override
|
||||
public int max() {
|
||||
return max;
|
||||
return finalMax;
|
||||
}
|
||||
@Override
|
||||
public String flags() {
|
||||
|
@ -76,8 +76,6 @@ public class Settings extends Config {
|
||||
@Comment({
|
||||
"Put any minecraft or mod jars for FAWE to be aware of block textures",
|
||||
})
|
||||
public String PATTERNS = "patterns";
|
||||
public String MASKS = "masks";
|
||||
public String TEXTURES = "textures";
|
||||
public String HEIGHTMAP = "heightmap";
|
||||
public String HISTORY = "history";
|
||||
@ -88,6 +86,7 @@ public class Settings extends Config {
|
||||
public String CLIPBOARD = "clipboard";
|
||||
@Comment("Each player has their own sub directory for schematics")
|
||||
public boolean PER_PLAYER_SCHEMATICS = true;
|
||||
public String COMMANDS = "commands";
|
||||
}
|
||||
|
||||
@Comment("Region restriction settings")
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.boydti.fawe.object;
|
||||
|
||||
public abstract class RunnableVal2<T, U> implements Runnable {
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public abstract class RunnableVal2<T, U> implements Runnable, BiConsumer<T, U> {
|
||||
public T value1;
|
||||
public U value2;
|
||||
|
||||
@ -23,4 +25,9 @@ public abstract class RunnableVal2<T, U> implements Runnable {
|
||||
run(value1, value2);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(T t, U u) {
|
||||
run(t, u);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,9 @@
|
||||
package com.boydti.fawe.object.clipboard;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import jdk.nashorn.internal.ir.Block;
|
||||
|
||||
public class OffsetFaweClipboard extends AbstractDelegateFaweClipboard {
|
||||
private final int ox, oy, oz;
|
||||
|
@ -1,15 +1,9 @@
|
||||
package com.boydti.fawe.object.pattern;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import jdk.nashorn.internal.ir.Block;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
@ -56,6 +56,13 @@ public class MutableCharSequence implements CharSequence {
|
||||
return str.substring(start, start + length);
|
||||
}
|
||||
|
||||
public int indexOf(char c) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (charAt(i) == c) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
CharSequence anotherString = (CharSequence) obj;
|
||||
|
@ -31,6 +31,7 @@ import java.util.Map.Entry;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.*;
|
||||
import javax.imageio.ImageIO;
|
||||
@ -151,13 +152,13 @@ public class MainUtil {
|
||||
new Exception().printStackTrace();
|
||||
}
|
||||
|
||||
public static void traverse(Path path, final RunnableVal2<Path, BasicFileAttributes> onEach) {
|
||||
public static void traverse(Path path, final BiConsumer<Path, BasicFileAttributes> onEach) {
|
||||
try {
|
||||
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult
|
||||
visitFile(Path file, BasicFileAttributes attrs) {
|
||||
onEach.run(file, attrs);
|
||||
onEach.accept(file, attrs);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,8 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
public class StringMan {
|
||||
public static String replaceFromMap(final String string, final Map<String, String> replacements) {
|
||||
@ -33,6 +35,13 @@ public class StringMan {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static boolean containsAny(CharSequence sequence, String any) {
|
||||
for (int i = 0; i < sequence.length(); i++) {
|
||||
if (any.indexOf(sequence.charAt(i)) != -1) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int findMatchingBracket(CharSequence sequence, int index) {
|
||||
char startC = sequence.charAt(index);
|
||||
char lookC = getMatchingBracket(startC);
|
||||
|
@ -504,7 +504,7 @@ public class TextureUtil implements TextureHolder{
|
||||
}
|
||||
|
||||
public BiomeColor getNearestBiome(int color) {
|
||||
int grass = blockColors[2 << 4];
|
||||
int grass = blockColors[BlockTypes.GRASS_BLOCK.getInternalId()];
|
||||
if (grass == 0) {
|
||||
return null;
|
||||
}
|
||||
|
@ -25,12 +25,14 @@ import com.boydti.fawe.util.MainUtil;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.command.ClipboardCommands;
|
||||
import com.sk89q.worldedit.command.FlattenedClipboardTransform;
|
||||
import com.sk89q.worldedit.command.SchematicCommands;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
@ -84,7 +86,7 @@ public class CuboidClipboard {
|
||||
}
|
||||
}
|
||||
|
||||
private final BlockArrayClipboard clipboard;
|
||||
private BlockArrayClipboard clipboard;
|
||||
private AffineTransform transform;
|
||||
public Vector size;
|
||||
|
||||
@ -441,7 +443,14 @@ public class CuboidClipboard {
|
||||
@Deprecated
|
||||
public void saveSchematic(File path) throws IOException, DataException {
|
||||
checkNotNull(path);
|
||||
SchematicFormat.MCEDIT.save(this, path);
|
||||
if (transform != null && !transform.isIdentity()) {
|
||||
final FlattenedClipboardTransform result = FlattenedClipboardTransform.transform(clipboard, transform);
|
||||
BlockArrayClipboard target = new BlockArrayClipboard(result.getTransformedRegion(), UUID.randomUUID());
|
||||
target.setOrigin(clipboard.getOrigin());
|
||||
Operations.completeLegacy(result.copyTo(target));
|
||||
this.clipboard = target;
|
||||
}
|
||||
new Schematic(clipboard).save(path, ClipboardFormat.SPONGE_SCHEMATIC);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1548,7 +1548,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
||||
checkNotNull(region);
|
||||
checkNotNull(block);
|
||||
if (canBypassAll(region, false, true) && !block.hasNbtData()) {
|
||||
return changes = queue.setBlocks((CuboidRegion) region, block.getInternalPropertiesId());
|
||||
return changes = queue.setBlocks((CuboidRegion) region, block.getInternalId());
|
||||
}
|
||||
try {
|
||||
if (hasExtraExtents()) {
|
||||
@ -1584,8 +1584,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
||||
if (pattern instanceof BlockPattern) {
|
||||
return setBlocks(region, ((BlockPattern) pattern).getBlock());
|
||||
}
|
||||
if (pattern instanceof BaseBlock) {
|
||||
return setBlocks(region, (BaseBlock) pattern);
|
||||
if (pattern instanceof BlockStateHolder) {
|
||||
return setBlocks(region, (BlockStateHolder) pattern);
|
||||
}
|
||||
final BlockReplace replace = new BlockReplace(EditSession.this, pattern);
|
||||
final RegionVisitor visitor = new RegionVisitor(region, replace, queue instanceof MappedFaweQueue ? (MappedFaweQueue) queue : null);
|
||||
|
@ -19,19 +19,12 @@
|
||||
|
||||
package com.sk89q.worldedit.blocks;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.worldedit.PlayerDirection;
|
||||
import com.sk89q.worldedit.registry.state.PropertyGroup;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import jdk.nashorn.internal.ir.Block;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Block types.
|
||||
|
@ -62,7 +62,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"false"},
|
||||
aliases = {"false", "#false"},
|
||||
desc = "Always false"
|
||||
)
|
||||
public Mask falseMask(Extent extent) {
|
||||
@ -70,7 +70,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"true"},
|
||||
aliases = {"true", "#true"},
|
||||
desc = "Always true"
|
||||
)
|
||||
public Mask trueMask(Extent extent) {
|
||||
@ -262,7 +262,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"\\", "/", "#angle"},
|
||||
aliases = {"\\", "/", "#angle", "#\\", "#/"},
|
||||
desc = "Restrict to specific terrain angle",
|
||||
help = "Restrict to specific terrain angle\n" +
|
||||
"The -o flag will only overlay\n" +
|
||||
@ -289,7 +289,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"(", ")", "#roc"},
|
||||
aliases = {"(", ")", "#roc", "#(", "#)"},
|
||||
desc = "Restrict to near specific terrain slope rate of change",
|
||||
help = "Restrict to near specific terrain slope rate of change\n" +
|
||||
"The -o flag will only overlay\n" +
|
||||
@ -315,7 +315,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"^", "#extrema"},
|
||||
aliases = {"^", "#extrema", "#^"},
|
||||
desc = "Restrict to near specific terrain extrema",
|
||||
help = "Restrict to near specific terrain extrema\n" +
|
||||
"The -o flag will only overlay\n" +
|
||||
@ -342,7 +342,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"{"},
|
||||
aliases = {"{", "#{"},
|
||||
desc = "Restricts blocks to within a specific radius range of the initial block",
|
||||
usage = "<min> <max>",
|
||||
min = 2,
|
||||
@ -353,7 +353,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"|"},
|
||||
aliases = {"|", "#|", "#side"},
|
||||
desc = "sides with a specific number of other blocks",
|
||||
usage = "<mask> <min> <max>",
|
||||
min = 3,
|
||||
@ -364,7 +364,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"~"},
|
||||
aliases = {"~", "#~", "#adjacent"},
|
||||
desc = "Adjacent to a specific number of other blocks",
|
||||
usage = "<mask> [min=1] [max=8]",
|
||||
min = 1,
|
||||
@ -382,7 +382,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"<"},
|
||||
aliases = {"<", "#<", "#below"},
|
||||
desc = "below a specific block",
|
||||
usage = "<mask>",
|
||||
min = 1,
|
||||
@ -394,7 +394,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {">"},
|
||||
aliases = {">", "#>", "#above"},
|
||||
desc = "above a specific block",
|
||||
usage = "<mask>",
|
||||
min = 1,
|
||||
@ -406,7 +406,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"$", "#biome"},
|
||||
aliases = {"$", "#biome", "#$"},
|
||||
desc = "in a specific biome",
|
||||
help = "in a specific biome. For a list of biomes use //biomelist",
|
||||
usage = "<biome>",
|
||||
@ -418,7 +418,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"%"},
|
||||
aliases = {"%", "#%", "#percent"},
|
||||
desc = "percentage chance",
|
||||
usage = "<chance>",
|
||||
min = 1,
|
||||
@ -430,7 +430,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"="},
|
||||
aliases = {"=", "#=", "#expression"},
|
||||
desc = "expression mask",
|
||||
usage = "<expression>",
|
||||
min = 1,
|
||||
@ -444,7 +444,7 @@ public class MaskCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"!", "#not", "#negate"},
|
||||
aliases = {"!", "#not", "#negate", "#!"},
|
||||
desc = "Negate another mask",
|
||||
usage = "<mask>",
|
||||
min = 1,
|
||||
|
@ -418,7 +418,7 @@ public class PatternCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"="},
|
||||
aliases = {"=", "#=", "#expression"},
|
||||
desc = "Expression pattern: http://wiki.sk89q.com/wiki/WorldEdit/Expression_syntax",
|
||||
usage = "<expression>",
|
||||
min = 1,
|
||||
|
@ -382,11 +382,11 @@ public class SchematicCommands extends MethodCommands {
|
||||
|
||||
@Command(aliases = {"move", "m"}, usage = "<directory>", desc = "Move your loaded schematic", help = "Move your currently loaded schematics", min = 1, max = 1)
|
||||
@CommandPermissions({"worldedit.schematic.move", "worldedit.schematic.move.other"})
|
||||
public void move(final Player player, final LocalSession session, final CommandContext args) throws WorldEditException {
|
||||
public void move(final Player player, final LocalSession session, String directory) throws WorldEditException {
|
||||
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
||||
final File working = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||
final File dir = Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? new File(working, player.getUniqueId().toString()) : working;
|
||||
File destDir = new File(dir, args.getString(0));
|
||||
File destDir = new File(dir, directory);
|
||||
if (!MainUtil.isInSubDirectory(working, destDir)) {
|
||||
player.printError("Directory " + destDir + " does not exist!");
|
||||
return;
|
||||
|
@ -36,10 +36,8 @@ import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.event.platform.ConfigurationLoadEvent;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.extension.platform.PlatformManager;
|
||||
import com.sk89q.worldedit.extension.platform.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.text.DateFormat;
|
||||
@ -113,6 +111,7 @@ public class WorldEditCommands {
|
||||
we.getPlatformManager().queryCapability(Capability.CONFIGURATION).reload();
|
||||
we.getEventBus().post(new ConfigurationLoadEvent(we.getPlatformManager().queryCapability(Capability.CONFIGURATION).getConfiguration()));
|
||||
Fawe.get().setupConfigs();
|
||||
CommandManager.getInstance().register(we.getPlatformManager().queryCapability(Capability.USER_COMMANDS));
|
||||
actor.print(BBC.getPrefix() + "Reloaded WorldEdit " + we.getVersion() + " and FAWE (" + Fawe.get().getVersion() + ")");
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.extension.factory;
|
||||
|
||||
import com.boydti.fawe.command.SuggestInputParseException;
|
||||
import com.boydti.fawe.jnbt.JSON2NBT;
|
||||
import com.boydti.fawe.jnbt.NBTException;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
@ -26,6 +27,7 @@ import com.boydti.fawe.util.StringMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.blocks.MobSpawnerBlock;
|
||||
@ -50,6 +52,11 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Parses block input strings.
|
||||
@ -283,8 +290,13 @@ public class DefaultBlockParser extends InputParser<BlockStateHolder> {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!worldEdit.getPlatformManager().queryCapability(Capability.USER_COMMANDS).isValidMobType(mobName)) {
|
||||
throw new NoMatchException("Unknown mob type '" + mobName + "'");
|
||||
Platform capability = worldEdit.getPlatformManager().queryCapability(Capability.USER_COMMANDS);
|
||||
if (!capability.isValidMobType(mobName)) {
|
||||
final String finalMobName = mobName.toLowerCase();
|
||||
throw new SuggestInputParseException("Unknown mob type '" + mobName + "'", mobName, () -> Stream.of(MobType.values())
|
||||
.map(m -> m.getName().toLowerCase())
|
||||
.filter(s -> s.startsWith(finalMobName))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
return new MobSpawnerBlock(state, mobName);
|
||||
} else {
|
||||
|
@ -1,11 +1,14 @@
|
||||
package com.sk89q.worldedit.extension.factory;
|
||||
|
||||
import com.boydti.fawe.command.FaweParser;
|
||||
import com.boydti.fawe.command.SuggestInputParseException;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.util.command.*;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.command.MaskCommands;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
@ -17,14 +20,18 @@ import com.sk89q.worldedit.function.mask.*;
|
||||
import com.sk89q.worldedit.internal.command.ActorAuthorizer;
|
||||
import com.sk89q.worldedit.internal.command.WorldEditBinding;
|
||||
import com.sk89q.worldedit.session.request.Request;
|
||||
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||
import com.sk89q.worldedit.util.command.SimpleDispatcher;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class DefaultMaskParser extends FaweParser<Mask> {
|
||||
private final Dispatcher dispatcher;
|
||||
@ -50,11 +57,11 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
||||
|
||||
@Override
|
||||
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
if (input.isEmpty()) return null;
|
||||
if (input.isEmpty()) {
|
||||
throw new SuggestInputParseException("No input provided", "", () -> Stream.concat(Stream.of("#", ",", "&"), BlockTypes.getNameSpaces().stream().map(n -> n + ":")).collect(Collectors.toList()));
|
||||
}
|
||||
Extent extent = Request.request().getExtent();
|
||||
if (extent == null) extent = context.getExtent();
|
||||
// List<Mask> intersection = new ArrayList<>();
|
||||
// List<Mask> union = new ArrayList<>();
|
||||
List<List<Mask>> masks = new ArrayList<>();
|
||||
masks.add(new ArrayList<>());
|
||||
|
||||
@ -63,12 +70,12 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
||||
if (actor != null) {
|
||||
locals.put(Actor.class, actor);
|
||||
}
|
||||
//
|
||||
try {
|
||||
List<Map.Entry<ParseEntry, List<String>>> parsed = parse(input);
|
||||
for (Map.Entry<ParseEntry, List<String>> entry : parsed) {
|
||||
ParseEntry pe = entry.getKey();
|
||||
String command = pe.input;
|
||||
final String command = pe.input;
|
||||
String full = pe.full;
|
||||
Mask mask = null;
|
||||
if (command.isEmpty()) {
|
||||
mask = parseFromInput(StringMan.join(entry.getValue(), ','), context);
|
||||
@ -79,76 +86,107 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
||||
if (charMask && input.charAt(0) == '=') {
|
||||
return parseFromInput(char0 + "[" + input.substring(1) + "]", context);
|
||||
}
|
||||
if (mask == null) {
|
||||
// Legacy syntax
|
||||
if (charMask) {
|
||||
switch (char0) {
|
||||
case '\\': //
|
||||
case '/': //
|
||||
case '{': //
|
||||
case '$': //
|
||||
case '%': {
|
||||
command = command.substring(1);
|
||||
String value = command + ((entry.getValue().isEmpty()) ? "" : "[" + StringMan.join(entry.getValue(), "][") + "]");
|
||||
if (value.contains(":")) {
|
||||
if (value.charAt(0) == ':') value.replaceFirst(":", "");
|
||||
value = value.replaceAll(":", "][");
|
||||
}
|
||||
mask = parseFromInput(char0 + "[" + value + "]", context);
|
||||
break;
|
||||
if (char0 == '#') {
|
||||
throw new SuggestInputParseException(new NoMatchException("Unkown mask: " + full + ", See: //masks"), full,
|
||||
() -> {
|
||||
if (full.length() == 1) return new ArrayList<>(dispatcher.getPrimaryAliases());
|
||||
return dispatcher.getAliases().stream().filter(
|
||||
s -> s.startsWith(command.toLowerCase())
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
case '|':
|
||||
case '~':
|
||||
case '<':
|
||||
case '>':
|
||||
case '!':
|
||||
input = input.substring(input.indexOf(char0) + 1);
|
||||
mask = parseFromInput(char0 + "[" + input + "]", context);
|
||||
if (actor != null) {
|
||||
BBC.COMMAND_CLARIFYING_BRACKET.send(actor, char0 + "[" + input + "]");
|
||||
}
|
||||
return mask;
|
||||
);
|
||||
}
|
||||
// Legacy syntax
|
||||
if (charMask) {
|
||||
switch (char0) {
|
||||
case '\\': //
|
||||
case '/': //
|
||||
case '{': //
|
||||
case '$': //
|
||||
case '%': {
|
||||
String value = command.substring(1) + ((entry.getValue().isEmpty()) ? "" : "[" + StringMan.join(entry.getValue(), "][") + "]");
|
||||
if (value.contains(":")) {
|
||||
if (value.charAt(0) == ':') value.replaceFirst(":", "");
|
||||
value = value.replaceAll(":", "][");
|
||||
}
|
||||
mask = parseFromInput("#" + char0 + "[" + value + "]", context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mask == null) {
|
||||
if (command.startsWith("[")) {
|
||||
int end = command.lastIndexOf(']');
|
||||
mask = parseFromInput(command.substring(1, end == -1 ? command.length() : end), context);
|
||||
} else {
|
||||
List<String> entries = entry.getValue();
|
||||
try {
|
||||
BlockMaskBuilder builder = new BlockMaskBuilder().addRegex(pe.full);
|
||||
if (builder.isEmpty()) {
|
||||
try {
|
||||
context.setPreferringWildcard(true);
|
||||
context.setRestricted(false);
|
||||
BlockStateHolder block = worldEdit.getBlockFactory().parseFromInput(pe.full, context);
|
||||
builder.add(block);
|
||||
} catch (NoMatchException e) {
|
||||
throw new NoMatchException(e.getMessage() + " See: //masks");
|
||||
}
|
||||
}
|
||||
mask = builder.build(extent);
|
||||
} catch (PatternSyntaxException regex) {
|
||||
throw new InputParseException(regex.getMessage());
|
||||
case '|':
|
||||
case '~':
|
||||
case '<':
|
||||
case '>':
|
||||
case '!':
|
||||
input = input.substring(input.indexOf(char0) + 1);
|
||||
mask = parseFromInput(char0 + "[" + input + "]", context);
|
||||
if (actor != null) {
|
||||
BBC.COMMAND_CLARIFYING_BRACKET.send(actor, char0 + "[" + input + "]");
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
}
|
||||
if (mask == null) {
|
||||
if (command.startsWith("[")) {
|
||||
int end = command.lastIndexOf(']');
|
||||
mask = parseFromInput(command.substring(1, end == -1 ? command.length() : end), context);
|
||||
} else {
|
||||
List<String> entries = entry.getValue();
|
||||
BlockMaskBuilder builder = new BlockMaskBuilder();
|
||||
// if (StringMan.containsAny(full, "\\^$.|?+(){}<>~$!%^&*+-/"))
|
||||
{
|
||||
try {
|
||||
builder.addRegex(full);
|
||||
} catch (SuggestInputParseException rethrow) {
|
||||
throw rethrow;
|
||||
} catch (InputParseException ignore) {}
|
||||
}
|
||||
if (mask == null) {
|
||||
context.setPreferringWildcard(true);
|
||||
context.setRestricted(false);
|
||||
BlockStateHolder block = worldEdit.getBlockFactory().parseFromInput(full, context);
|
||||
builder.add(block);
|
||||
mask = builder.build(extent);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<String> args = entry.getValue();
|
||||
if (!args.isEmpty()) {
|
||||
command += " " + StringMan.join(args, " ");
|
||||
String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " "));
|
||||
try {
|
||||
mask = (Mask) dispatcher.call(command + cmdArgs, locals, new String[0]);
|
||||
} catch (SuggestInputParseException rethrow) {
|
||||
throw rethrow;
|
||||
} catch (Throwable e) {
|
||||
throw SuggestInputParseException.of(e, full, () -> {
|
||||
try {
|
||||
List<String> suggestions = dispatcher.get(command).getCallable().getSuggestions(cmdArgs, locals);
|
||||
if (suggestions.size() <= 2) {
|
||||
for (int i = 0; i < suggestions.size(); i++) {
|
||||
String suggestion = suggestions.get(i);
|
||||
if (suggestion.indexOf(' ') != 0) {
|
||||
String[] split = suggestion.split(" ");
|
||||
suggestion = BBC.color("[" + StringMan.join(split, "][") + "]");
|
||||
suggestions.set(i, suggestion);
|
||||
}
|
||||
}
|
||||
}
|
||||
return suggestions;
|
||||
} catch (CommandException e1) {
|
||||
throw new InputParseException(e1.getMessage());
|
||||
} catch (Throwable e2) {
|
||||
e2.printStackTrace();
|
||||
throw new InputParseException(e2.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
mask = (Mask) dispatcher.call(command, locals, new String[0]);
|
||||
}
|
||||
if (pe.and) {
|
||||
masks.add(new ArrayList<>());
|
||||
}
|
||||
masks.get(masks.size() - 1).add(mask);
|
||||
}
|
||||
} catch (InputParseException ignore) {
|
||||
throw ignore;
|
||||
} catch (InputParseException rethrow) {
|
||||
throw rethrow;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
throw new InputParseException(e.getMessage(), e);
|
||||
@ -169,6 +207,4 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.sk89q.worldedit.extension.factory;
|
||||
|
||||
import com.boydti.fawe.command.FaweParser;
|
||||
import com.boydti.fawe.command.SuggestInputParseException;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.random.TrueRandom;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
@ -20,9 +22,13 @@ import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||
import com.sk89q.worldedit.util.command.SimpleDispatcher;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
private final Dispatcher dispatcher;
|
||||
@ -47,7 +53,9 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
|
||||
@Override
|
||||
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
if (input.isEmpty()) return null;
|
||||
if (input.isEmpty()) {
|
||||
throw new SuggestInputParseException("No input provided", "", () -> Stream.concat(Stream.of("#", ",", "&"), BlockTypes.getNameSpaces().stream().map(n -> n + ":")).collect(Collectors.toList()));
|
||||
}
|
||||
List<Double> chances = new ArrayList<>();
|
||||
List<Pattern> patterns = new ArrayList<>();
|
||||
final CommandLocals locals = new CommandLocals();
|
||||
@ -58,7 +66,8 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
try {
|
||||
for (Map.Entry<ParseEntry, List<String>> entry : parse(input)) {
|
||||
ParseEntry pe = entry.getKey();
|
||||
String command = pe.input;
|
||||
final String command = pe.input;
|
||||
String full = pe.full;
|
||||
Pattern pattern = null;
|
||||
double chance = 1;
|
||||
if (command.isEmpty()) {
|
||||
@ -70,11 +79,22 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
if (charMask && input.charAt(0) == '=') {
|
||||
return parseFromInput(char0 + "[" + input.substring(1) + "]", context);
|
||||
}
|
||||
if (char0 == '#') {
|
||||
throw new SuggestInputParseException(new NoMatchException("Unkown pattern: " + full + ", See: //patterns"), full,
|
||||
() -> {
|
||||
if (full.length() == 1) return new ArrayList<>(dispatcher.getPrimaryAliases());
|
||||
return dispatcher.getAliases().stream().filter(
|
||||
s -> s.startsWith(command.toLowerCase())
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (charMask) {
|
||||
switch (char0) {
|
||||
case '$': {
|
||||
command = command.substring(1);
|
||||
String value = command + ((entry.getValue().isEmpty()) ? "" : "[" + StringMan.join(entry.getValue(), "][") + "]");
|
||||
String value = command.substring(1) + ((entry.getValue().isEmpty()) ? "" : "[" + StringMan.join(entry.getValue(), "][") + "]");
|
||||
if (value.contains(":")) {
|
||||
if (value.charAt(0) == ':') value.replaceFirst(":", "");
|
||||
value = value.replaceAll(":", "][");
|
||||
@ -92,12 +112,12 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
int percentIndex = command.indexOf('%');
|
||||
if (percentIndex != -1) { // Legacy percent pattern
|
||||
chance = Expression.compile(command.substring(0, percentIndex)).evaluate();
|
||||
command = command.substring(percentIndex + 1);
|
||||
String value = command.substring(percentIndex + 1);
|
||||
if (!entry.getValue().isEmpty()) {
|
||||
if (!command.isEmpty()) command += " ";
|
||||
command += StringMan.join(entry.getValue(), " ");
|
||||
if (!value.isEmpty()) value += " ";
|
||||
value += StringMan.join(entry.getValue(), " ");
|
||||
}
|
||||
pattern = parseFromInput(command, context);
|
||||
pattern = parseFromInput(value, context);
|
||||
} else { // legacy block pattern
|
||||
try {
|
||||
pattern = worldEdit.getBlockFactory().parseFromInput(pe.full, context);
|
||||
@ -109,18 +129,45 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
}
|
||||
} else {
|
||||
List<String> args = entry.getValue();
|
||||
if (!args.isEmpty()) {
|
||||
command += " " + StringMan.join(args, " ");
|
||||
String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " "));
|
||||
try {
|
||||
pattern = (Pattern) dispatcher.call(command + cmdArgs, locals, new String[0]);
|
||||
} catch (SuggestInputParseException rethrow) {
|
||||
throw rethrow;
|
||||
} catch (Throwable e) {
|
||||
throw SuggestInputParseException.of(e, full, () -> {
|
||||
try {
|
||||
List<String> suggestions = dispatcher.get(command).getCallable().getSuggestions(cmdArgs, locals);
|
||||
if (suggestions.size() <= 2) {
|
||||
for (int i = 0; i < suggestions.size(); i++) {
|
||||
String suggestion = suggestions.get(i);
|
||||
if (suggestion.indexOf(' ') != 0) {
|
||||
String[] split = suggestion.split(" ");
|
||||
suggestion = BBC.color("[" + StringMan.join(split, "][") + "]");
|
||||
suggestions.set(i, suggestion);
|
||||
}
|
||||
}
|
||||
}
|
||||
return suggestions;
|
||||
} catch (CommandException e1) {
|
||||
throw new InputParseException(e1.getMessage());
|
||||
} catch (Throwable e2) {
|
||||
e2.printStackTrace();
|
||||
throw new InputParseException(e2.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
pattern = (Pattern) dispatcher.call(command, locals, new String[0]);
|
||||
}
|
||||
if (pattern != null) {
|
||||
patterns.add(pattern);
|
||||
chances.add(chance);
|
||||
}
|
||||
}
|
||||
} catch (CommandException | ExpressionException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InputParseException rethrow) {
|
||||
throw rethrow;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
throw new InputParseException(e.getMessage(), e);
|
||||
}
|
||||
if (patterns.isEmpty()) {
|
||||
return null;
|
||||
|
@ -39,7 +39,6 @@ public final class MaskFactory extends AbstractFactory<Mask> {
|
||||
*/
|
||||
public MaskFactory(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
|
||||
parsers.add(new DefaultMaskParser(worldEdit));
|
||||
}
|
||||
|
||||
|
@ -39,9 +39,7 @@ public final class PatternFactory extends AbstractFactory<Pattern> {
|
||||
*/
|
||||
public PatternFactory(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
|
||||
parsers.add(new HashTagPatternParser(worldEdit));
|
||||
parsers.add(new SingleBlockPatternParser(worldEdit));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -334,7 +334,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
|
||||
|
||||
@Override
|
||||
public Location getBlockIn() {
|
||||
return getLocation();
|
||||
Location loc = getLocation();
|
||||
return new Location(loc.getExtent(), loc.toBlockVector(), loc.getDirection());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,8 +48,10 @@ import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
|
||||
import com.sk89q.worldedit.function.factory.Deform;
|
||||
import com.sk89q.worldedit.function.factory.Deform.Mode;
|
||||
import com.sk89q.worldedit.internal.command.*;
|
||||
import com.sk89q.worldedit.scripting.CommandScriptLoader;
|
||||
import com.sk89q.worldedit.session.request.Request;
|
||||
import com.sk89q.worldedit.util.auth.AuthorizationException;
|
||||
import com.sk89q.worldedit.util.command.CallableProcessor;
|
||||
import com.sk89q.worldedit.util.command.CommandCallable;
|
||||
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||
import com.sk89q.worldedit.util.command.InvalidUsageException;
|
||||
@ -184,13 +186,13 @@ public final class CommandManager {
|
||||
* @param clazz The class containing all the sub command methods
|
||||
* @param aliases The aliases to give the command
|
||||
*/
|
||||
public void registerCommands(Object clazz, Object processor, String... aliases) {
|
||||
public void registerCommands(Object clazz, CallableProcessor processor, String... aliases) {
|
||||
if (platform != null) {
|
||||
if (aliases.length == 0) {
|
||||
builder.registerMethodsAsCommands(dispatcher, clazz);
|
||||
builder.registerMethodsAsCommands(dispatcher, clazz, processor);
|
||||
} else {
|
||||
DispatcherNode graph = new CommandGraph().builder(builder).commands();
|
||||
graph = graph.registerMethods(clazz);
|
||||
graph = graph.registerMethods(clazz, processor);
|
||||
dispatcher.registerCommand(graph.graph().getDispatcher(), aliases);
|
||||
}
|
||||
platform.registerCommands(dispatcher);
|
||||
@ -298,6 +300,13 @@ public final class CommandManager {
|
||||
|
||||
public void register(Platform platform) {
|
||||
log.log(Level.FINE, "Registering commands with " + platform.getClass().getCanonicalName());
|
||||
this.platform = null;
|
||||
|
||||
try {
|
||||
new CommandScriptLoader().load();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
LocalConfiguration config = platform.getConfiguration();
|
||||
boolean logging = config.logCommands;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.sk89q.worldedit.extent.transform;
|
||||
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.jnbt.ByteTag;
|
||||
@ -10,29 +9,23 @@ import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.internal.helper.MCDirections;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.registry.state.AbstractProperty;
|
||||
import com.sk89q.worldedit.registry.state.DirectionalProperty;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.block.*;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.registry.BlockRegistry;
|
||||
import jdk.nashorn.internal.ir.Block;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Transforms blocks themselves (but not their position) according to a
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.sk89q.worldedit.function.mask;
|
||||
|
||||
import com.boydti.fawe.command.SuggestInputParseException;
|
||||
import com.boydti.fawe.object.collection.FastBitSet;
|
||||
import com.boydti.fawe.object.string.MutableCharSequence;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
@ -15,7 +16,10 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BlockMaskBuilder {
|
||||
private static final Operator GREATER = (a, b) -> a > b;
|
||||
@ -30,41 +34,51 @@ public class BlockMaskBuilder {
|
||||
boolean test(int left, int right);
|
||||
}
|
||||
|
||||
public BlockMaskBuilder filterRegex(BlockType blockType, PropertyKey key, String regex) {
|
||||
private boolean filterRegex(BlockType blockType, PropertyKey key, String regex) {
|
||||
Property property = blockType.getProperty(key);
|
||||
if (property == null) return this;
|
||||
if (property == null) return false;
|
||||
List values = property.getValues();
|
||||
boolean result = false;
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
Object value = values.get(i);
|
||||
if (!value.toString().matches(regex)) {
|
||||
if (!value.toString().matches(regex) && has(blockType, property, i)) {
|
||||
filter(blockType, property, i);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
return result;
|
||||
}
|
||||
|
||||
private void filterOperator(BlockType blockType, PropertyKey key, Operator operator, CharSequence value) {
|
||||
private boolean filterOperator(BlockType blockType, PropertyKey key, Operator operator, CharSequence value) {
|
||||
Property property = blockType.getProperty(key);
|
||||
if (property == null) return;
|
||||
if (property == null) return false;
|
||||
int index = property.getIndexFor(value);
|
||||
List values = property.getValues();
|
||||
boolean result = false;
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
if (!operator.test(index, i)) {
|
||||
if (!operator.test(index, i) && has(blockType, property, i)) {
|
||||
filter(blockType, property, i);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void filterRegexOrOperator(BlockType type, PropertyKey key, Operator operator, CharSequence value) {
|
||||
private boolean filterRegexOrOperator(BlockType type, PropertyKey key, Operator operator, CharSequence value) {
|
||||
boolean result = false;
|
||||
if (!type.hasProperty(key)) {
|
||||
if (operator == EQUAL) remove(type);
|
||||
if (operator == EQUAL) {
|
||||
result = bitSets[type.getInternalId()] != null;
|
||||
remove(type);
|
||||
}
|
||||
} else if (value.length() == 0) {
|
||||
|
||||
} else if ((operator == EQUAL || operator == EQUAL_OR_NULL) && !StringMan.isAlphanumericUnd(value)) {
|
||||
filterRegex(type, key, value.toString());
|
||||
result = filterRegex(type, key, value.toString());
|
||||
} else {
|
||||
filterOperator(type, key, operator, value);
|
||||
result = filterOperator(type, key, operator, value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public BlockMaskBuilder addRegex(String input) throws InputParseException {
|
||||
@ -90,8 +104,13 @@ public class BlockMaskBuilder {
|
||||
add(myType);
|
||||
}
|
||||
}
|
||||
if (blockTypeList.isEmpty()) {
|
||||
throw new InputParseException("No block found for " + input);
|
||||
}
|
||||
if (blockTypeList.size() == 1) type = blockTypeList.get(0);
|
||||
}
|
||||
// Empty string
|
||||
charSequence.setSubstring(0, 0);
|
||||
|
||||
PropertyKey key = null;
|
||||
int length = input.length();
|
||||
@ -109,13 +128,40 @@ public class BlockMaskBuilder {
|
||||
case ']':
|
||||
case ',': {
|
||||
charSequence.setSubstring(last, i);
|
||||
char firstChar = input.charAt(last + 1);
|
||||
if (type != null) filterRegexOrOperator(type, key, operator, charSequence);
|
||||
if (key == null && PropertyKey.get(charSequence) == null) suggest(input, charSequence.toString(), type != null ? Collections.singleton(type) : blockTypeList);
|
||||
if (operator == null) throw new SuggestInputParseException("No operator for " + input, "", () -> Arrays.asList("=", "~", "!", "<", ">", "<=", ">="));
|
||||
boolean filtered = false;
|
||||
if (type != null) {
|
||||
filtered = filterRegexOrOperator(type, key, operator, charSequence);
|
||||
}
|
||||
else {
|
||||
for (BlockTypes myType : blockTypeList) {
|
||||
filterRegexOrOperator(myType, key, operator, charSequence);
|
||||
filtered |= filterRegexOrOperator(myType, key, operator, charSequence);
|
||||
}
|
||||
}
|
||||
if (!filtered) {
|
||||
String value = charSequence.toString();
|
||||
final PropertyKey fKey = key;
|
||||
Collection<BlockTypes> types = type != null ? Collections.singleton(type) : blockTypeList;
|
||||
throw new SuggestInputParseException("No value for " + input, input, () -> {
|
||||
HashSet<String> values = new HashSet<>();
|
||||
types.forEach(t -> {
|
||||
if (t.hasProperty(fKey)) {
|
||||
Property p = t.getProperty(fKey);
|
||||
for (int j = 0; j < p.getValues().size(); j++) {
|
||||
if (has(t, p, j)) {
|
||||
String o = p.getValues().get(j).toString();
|
||||
if (o.startsWith(value)) values.add(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return new ArrayList<>(values);
|
||||
});
|
||||
}
|
||||
// Reset state
|
||||
key = null;
|
||||
operator = null;
|
||||
last = i + 1;
|
||||
break;
|
||||
}
|
||||
@ -144,7 +190,11 @@ public class BlockMaskBuilder {
|
||||
operator = extra ? GREATER_EQUAL : GREATER;
|
||||
break;
|
||||
}
|
||||
if (charSequence.length() > 0) key = PropertyKey.get(charSequence);
|
||||
if (charSequence.length() > 0 || key == null) {
|
||||
key = PropertyKey.get(charSequence);
|
||||
if (key == null)
|
||||
suggest(input, charSequence.toString(), type != null ? Collections.singleton(type) : blockTypeList);
|
||||
}
|
||||
last = i + 1;
|
||||
break;
|
||||
}
|
||||
@ -166,7 +216,24 @@ public class BlockMaskBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
///// end test /////
|
||||
private boolean has(BlockType type, Property property, int index) {
|
||||
AbstractProperty prop = (AbstractProperty) property;
|
||||
long[] states = bitSets[type.getInternalId()];
|
||||
if (states == null) return false;
|
||||
List values = prop.getValues();
|
||||
int localI = index << prop.getBitOffset() >> BlockTypes.BIT_OFFSET;
|
||||
return (states == BlockMask.ALL || FastBitSet.get(states, localI));
|
||||
}
|
||||
|
||||
private void suggest(String input, String property, Collection<BlockTypes> finalTypes) throws InputParseException {
|
||||
throw new SuggestInputParseException(input + " does not have: " + property, input, () -> {
|
||||
Set<PropertyKey> keys = new HashSet<>();
|
||||
finalTypes.forEach(t -> t.getProperties().stream().forEach(p -> keys.add(p.getKey())));
|
||||
return keys.stream().map(p -> p.getId()).filter(p -> p.startsWith(property)).collect(Collectors.toList());
|
||||
});
|
||||
}
|
||||
|
||||
///// end internal /////
|
||||
|
||||
private long[][] bitSets;
|
||||
|
||||
@ -230,7 +297,9 @@ public class BlockMaskBuilder {
|
||||
|
||||
public BlockMaskBuilder filter(BlockType type) {
|
||||
for (int i = 0; i < bitSets.length; i++) {
|
||||
if (i != type.getInternalId()) bitSets[i] = null;
|
||||
if (i != type.getInternalId()) {
|
||||
bitSets[i] = null;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
package com.sk89q.worldedit.internal.command;
|
||||
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.IncompleteRegionException;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
@ -355,18 +356,7 @@ public class WorldEditBinding extends BindingHelper {
|
||||
public BaseBiome getBiomeType(ArgumentStack context) throws ParameterException, WorldEditException {
|
||||
String input = context.next();
|
||||
if (input != null) {
|
||||
Actor actor = context.getContext().getLocals().get(Actor.class);
|
||||
World world;
|
||||
if (actor instanceof Entity) {
|
||||
Extent extent = ((Entity) actor).getExtent();
|
||||
if (extent instanceof World) {
|
||||
world = (World) extent;
|
||||
} else {
|
||||
throw new ParameterException("A world is required.");
|
||||
}
|
||||
} else {
|
||||
throw new ParameterException("An entity is required.");
|
||||
}
|
||||
if (MathMan.isInteger(input)) return new BaseBiome(Integer.parseInt(input));
|
||||
|
||||
BiomeRegistry biomeRegistry = WorldEdit.getInstance().getPlatformManager()
|
||||
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry();
|
||||
|
@ -21,6 +21,7 @@ package com.sk89q.worldedit.registry.state;
|
||||
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@ -36,6 +37,7 @@ public class DirectionalProperty extends AbstractProperty<Direction> {
|
||||
public DirectionalProperty(final String name, final List<Direction> values, int bitOffset) {
|
||||
super(name, values, bitOffset);
|
||||
this.map = new int[Direction.values().length];
|
||||
Arrays.fill(this.map, -1);
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
this.map[values.get(i).ordinal()] = i;
|
||||
}
|
||||
@ -53,7 +55,9 @@ public class DirectionalProperty extends AbstractProperty<Direction> {
|
||||
|
||||
@Override
|
||||
public int getIndexFor(CharSequence string) throws IllegalArgumentException {
|
||||
return getIndex(Direction.get(string));
|
||||
Direction dir = Direction.get(string);
|
||||
if (dir == null) return -1;
|
||||
return getIndex(dir);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -51,7 +51,8 @@ public class EnumProperty extends AbstractProperty<String> {
|
||||
|
||||
@Override
|
||||
public int getIndexFor(CharSequence string) throws IllegalArgumentException {
|
||||
return offsets.get(string);
|
||||
Integer value = offsets.get(string);
|
||||
return value == null ? -1 : value;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -0,0 +1,106 @@
|
||||
package com.sk89q.worldedit.scripting;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweAPI;
|
||||
import com.boydti.fawe.command.FaweParser;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.BrushProcessor;
|
||||
import com.sk89q.worldedit.extension.factory.DefaultMaskParser;
|
||||
import com.sk89q.worldedit.extension.factory.HashTagPatternParser;
|
||||
import com.sk89q.worldedit.extension.platform.CommandManager;
|
||||
import com.sk89q.worldedit.util.command.CallableProcessor;
|
||||
import com.sk89q.worldedit.util.command.ProcessedCallable;
|
||||
import com.sk89q.worldedit.util.command.parametric.FunctionParametricCallable;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class CommandScriptLoader {
|
||||
private final NashornCraftScriptEngine engine;
|
||||
private final String loader;
|
||||
|
||||
public CommandScriptLoader() throws IOException {
|
||||
this.engine = new NashornCraftScriptEngine();
|
||||
|
||||
try (InputStream inputStream = WorldEdit.class.getResourceAsStream("/cs_adv.js")) {
|
||||
this.loader = CharStreams.toString(new InputStreamReader(inputStream, Charsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all file commands
|
||||
* @throws Throwable
|
||||
*/
|
||||
public void load() throws Throwable {
|
||||
File commands = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.COMMANDS);
|
||||
if (commands.exists()) {
|
||||
for (File file : commands.listFiles()) add(new String[0], file);
|
||||
}
|
||||
}
|
||||
|
||||
private void add(String[] aliases, File file) throws Throwable {
|
||||
if (file.isDirectory()) {
|
||||
if (aliases.length == 0) {
|
||||
String[] newAliases = new String[] {file.getName()};
|
||||
for (File newFile : file.listFiles()) {
|
||||
add(newAliases, newFile);
|
||||
}
|
||||
} else {
|
||||
Fawe.debug("Ignoring nested directory: " + file);
|
||||
}
|
||||
} else {
|
||||
String name = file.getName();
|
||||
if (name.endsWith(".js")) {
|
||||
Fawe.debug("Loading script: " + name);
|
||||
List<FunctionParametricCallable> cmds = getCommands(file, Collections.emptyMap());
|
||||
FaweParser parser = null;
|
||||
if (aliases.length == 1) {
|
||||
switch (aliases[0]) {
|
||||
case "brush":
|
||||
if (!cmds.isEmpty()) {
|
||||
BrushProcessor processor = new BrushProcessor(WorldEdit.getInstance());
|
||||
for (FunctionParametricCallable cmd : cmds) {
|
||||
ProcessedCallable processed = new ProcessedCallable(cmd, processor);
|
||||
CommandManager.getInstance().registerCommand(aliases, cmd.getCommand(), processed);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case "patterns":
|
||||
parser = FaweAPI.getParser(HashTagPatternParser.class);
|
||||
break;
|
||||
case "masks":
|
||||
parser = FaweAPI.getParser(DefaultMaskParser.class);
|
||||
break;
|
||||
}
|
||||
if (parser != null) {
|
||||
for (FunctionParametricCallable cmd : cmds) {
|
||||
parser.getDispatcher().registerCommand(cmd, cmd.getCommand().aliases());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (FunctionParametricCallable cmd : cmds) {
|
||||
CommandManager.getInstance().registerCommand(aliases, cmd.getCommand(), cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<FunctionParametricCallable> getCommands(File file, Map<String, Object> vars) throws Throwable {
|
||||
String script = new String(Files.readAllBytes(file.toPath())) + loader;
|
||||
return (List) engine.evaluate(script, file.getPath(), vars);
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.scripting;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptException;
|
||||
import javax.script.SimpleBindings;
|
||||
import java.util.Map;
|
||||
|
||||
public class NashornCraftScriptEngine implements CraftScriptEngine {
|
||||
private static NashornScriptEngineFactory FACTORY;
|
||||
private int timeLimit;
|
||||
|
||||
@Override
|
||||
public void setTimeLimit(int milliseconds) {
|
||||
timeLimit = milliseconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTimeLimit() {
|
||||
return timeLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object evaluate(String script, String filename, Map<String, Object> args) throws Throwable {
|
||||
ClassLoader cl = Fawe.get().getClass().getClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(cl);
|
||||
synchronized (NashornCraftScriptEngine.class) {
|
||||
if (FACTORY == null) FACTORY = new NashornScriptEngineFactory();
|
||||
}
|
||||
;
|
||||
ScriptEngine engine = FACTORY.getScriptEngine("--language=es6");
|
||||
SimpleBindings bindings = new SimpleBindings();
|
||||
|
||||
for (Map.Entry<String, Object> entry : args.entrySet()) {
|
||||
bindings.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
try {
|
||||
Object result = engine.eval(script, bindings);
|
||||
return result;
|
||||
} catch (Error e) {
|
||||
e.printStackTrace();
|
||||
throw new ScriptException(e.getMessage());
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
while (e.getCause() != null) {
|
||||
e = e.getCause();
|
||||
}
|
||||
if (e instanceof WorldEditException) {
|
||||
throw e;
|
||||
}
|
||||
throw e;
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -72,6 +72,7 @@ public class SimpleDispatcher implements Dispatcher {
|
||||
continue;
|
||||
} else {
|
||||
Fawe.debug("Replacing commands is currently undefined behavior: " + StringMan.getString(alias));
|
||||
commands.put(lower, mapping);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -86,8 +86,8 @@ public final class PrimitiveBindings extends BindingHelper {
|
||||
* @throws ParameterException on error
|
||||
*/
|
||||
@BindingMatch(type = { Boolean.class, boolean.class },
|
||||
behavior = BindingBehavior.CONSUMES,
|
||||
consumedCount = 1)
|
||||
behavior = BindingBehavior.CONSUMES,
|
||||
consumedCount = 1)
|
||||
public Boolean getBoolean(ArgumentStack context) throws ParameterException {
|
||||
return context.nextBoolean();
|
||||
}
|
||||
@ -117,7 +117,6 @@ public final class PrimitiveBindings extends BindingHelper {
|
||||
throw new ParameterException(String.format(
|
||||
"Expected '%s' to be a number or valid math expression (error: %s)", input, e.getMessage()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
package com.sk89q.worldedit.util.command.parametric;
|
||||
|
||||
import com.boydti.fawe.command.SuggestInputParseException;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.util.chat.UsageMessage;
|
||||
import com.sk89q.minecraft.util.commands.*;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.util.command.*;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class AParametricCallable implements CommandCallable {
|
||||
// private final ParametricBuilder builder;
|
||||
@ -206,101 +206,95 @@ public abstract class AParametricCallable implements CommandCallable {
|
||||
@Override
|
||||
public List<String> getSuggestions(String arguments, CommandLocals locals) throws CommandException {
|
||||
String[] split = ("ignored" + " " + arguments).split(" ", -1);
|
||||
|
||||
// &a<current> &f<next>
|
||||
// &cerrors
|
||||
|
||||
CommandContext context = new CommandContext(split, getValueFlags(), !arguments.endsWith(" "), locals);
|
||||
ContextArgumentStack scoped = new ContextArgumentStack(context);
|
||||
SuggestionContext suggestable = context.getSuggestionContext();
|
||||
|
||||
List<String> suggestions = new ArrayList<>(2);
|
||||
ParameterData parameter = null;
|
||||
ParameterData[] parameters = getParameters();
|
||||
String consumed = "";
|
||||
|
||||
// For /command -f |
|
||||
// For /command -f flag|
|
||||
if (suggestable.forFlag()) {
|
||||
for (int i = 0; i < getParameters().length; i++) {
|
||||
ParameterData parameter = getParameters()[i];
|
||||
boolean hasSuggestion = false;
|
||||
int maxConsumedI = 0; // The maximum argument index
|
||||
int minConsumedI = 0; // The minimum argument that has been consumed
|
||||
// Collect parameters
|
||||
try {
|
||||
for (;maxConsumedI < parameters.length; maxConsumedI++) {
|
||||
parameter = parameters[maxConsumedI];
|
||||
if (parameter.getBinding().getBehavior(parameter) != BindingBehavior.PROVIDES) {
|
||||
// Parse the user input into a method argument
|
||||
ArgumentStack usedArguments = getScopedContext(parameter, scoped);
|
||||
|
||||
if (parameter.getFlag() == suggestable.getFlag()) {
|
||||
String prefix = context.getFlag(parameter.getFlag());
|
||||
if (prefix == null) {
|
||||
prefix = "";
|
||||
}
|
||||
|
||||
// System.out.println("(0) Return get binding suggestions " + parameter + " | " + prefix);
|
||||
return parameter.getBinding().getSuggestions(parameter, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
// This should not happen
|
||||
// System.out.println("(1) This should not happen");
|
||||
return new ArrayList<String>();
|
||||
}
|
||||
|
||||
int consumerIndex = 0;
|
||||
ParameterData lastConsumer = null;
|
||||
String lastConsumed = null;
|
||||
|
||||
for (int i = 0; i < getParameters().length; i++) {
|
||||
ParameterData parameter = getParameters()[i];
|
||||
if (parameter.getFlag() != null) {
|
||||
continue; // We already handled flags
|
||||
}
|
||||
try {
|
||||
scoped.mark();
|
||||
parameter.getBinding().bind(parameter, scoped, true);
|
||||
if (scoped.wasConsumed()) {
|
||||
lastConsumer = parameter;
|
||||
lastConsumed = context.getString(scoped.position() - 1);
|
||||
consumerIndex++;
|
||||
}
|
||||
} catch (MissingParameterException e) {
|
||||
// For /command value1 |value2
|
||||
// For /command |value1 value2
|
||||
if (suggestable.forHangingValue()) {
|
||||
// System.out.println("(2) Return get binding dangling " + parameter + " | " + "");
|
||||
return parameter.getBinding().getSuggestions(parameter, "");
|
||||
} else {
|
||||
// For /command value1| value2
|
||||
if (lastConsumer != null) {
|
||||
// System.out.println("(3) Return get consumed " + lastConsumer + " | " + lastConsumed);
|
||||
return lastConsumer.getBinding().getSuggestions(lastConsumer, lastConsumed);
|
||||
// For /command| value1 value2
|
||||
// This should never occur
|
||||
} else {
|
||||
// System.out.println("(4) Invalid suggestion context");
|
||||
throw new RuntimeException("Invalid suggestion context");
|
||||
usedArguments.mark();
|
||||
try {
|
||||
parameter.getBinding().bind(parameter, usedArguments, false);
|
||||
minConsumedI = maxConsumedI + 1;
|
||||
} catch (Throwable e) {
|
||||
while (e.getCause() != null && !(e instanceof ParameterException || e instanceof InvocationTargetException)) e = e.getCause();
|
||||
consumed = usedArguments.reset();
|
||||
// Not optional? Then we can't execute this command
|
||||
if (!parameter.isOptional()) {
|
||||
if (!(e instanceof MissingParameterException)) minConsumedI = maxConsumedI;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ParameterException | InvocationTargetException e) {
|
||||
SuggestInputParseException suggestion = SuggestInputParseException.get(e);
|
||||
if (suggestion != null) {
|
||||
// System.out.println("(5) Has suggestion " + suggestion.getSuggestions());
|
||||
return suggestion.getSuggestions();
|
||||
}
|
||||
if (suggestable.forHangingValue()) {
|
||||
String name = getDescription().getParameters().get(consumerIndex).getName();
|
||||
// System.out.println("(6) Has dangling invalid " + name + " | " + e.getMessage());
|
||||
throw new InvalidUsageException("For parameter '" + name + "': " + e.getMessage(), this);
|
||||
} else {
|
||||
// System.out.println("(7) HGet binding suggestions " + parameter + " | " + lastConsumed);
|
||||
return parameter.getBinding().getSuggestions(parameter, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
// For /command value1 value2 |
|
||||
if (suggestable.forHangingValue()) {
|
||||
// There's nothing that we can suggest because there's no more parameters
|
||||
// to add on, and we can't change the previous parameter
|
||||
// System.out.println("(7.1) No more parameters");
|
||||
return new ArrayList<String>();
|
||||
} else {
|
||||
// For /command value1 value2|
|
||||
if (lastConsumer != null) {
|
||||
// System.out.println("(8) Get binding suggestions " + lastConsumer + " | " + lastConsumed);
|
||||
return lastConsumer.getBinding().getSuggestions(lastConsumer, lastConsumed);
|
||||
// This should never occur
|
||||
if (minConsumedI >= maxConsumedI && (parameter == null || parameter.getType() == CommandContext.class)) checkUnconsumed(scoped);
|
||||
} catch (MissingParameterException ignore) {
|
||||
} catch (UnconsumedParameterException e) {
|
||||
suggestions.add(BBC.color("&cToo many parameters! Unused parameters: " + e.getUnconsumed()));
|
||||
} catch (ParameterException e) {
|
||||
String name = parameter.getName();
|
||||
suggestions.add(BBC.color("&cFor parameter '" + name + "': " + e.getMessage()));
|
||||
} catch (InvocationTargetException e) {
|
||||
SuggestInputParseException suggestion = SuggestInputParseException.get(e);
|
||||
if (suggestion != null && !suggestion.getSuggestions().isEmpty()) {
|
||||
hasSuggestion = true;
|
||||
suggestions.addAll(suggestion.getSuggestions());
|
||||
} else {
|
||||
// System.out.println("(9) Invalid suggestion context");
|
||||
throw new RuntimeException("Invalid suggestion context");
|
||||
Throwable t = e;
|
||||
while (t.getCause() != null) t = t.getCause();
|
||||
String msg = t.getMessage();
|
||||
String name = parameter.getName();
|
||||
if (msg != null && !msg.isEmpty()) suggestions.add(BBC.color("&cFor parameter '" + name + "': " + msg));
|
||||
}
|
||||
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
throw new WrappedCommandException(t);
|
||||
}
|
||||
// If there's 1 or less suggestions already, then show parameter suggestion
|
||||
if (!hasSuggestion && suggestions.size() <= 1) {
|
||||
StringBuilder suggestion = new StringBuilder();
|
||||
outer:
|
||||
for (String prefix = ""; minConsumedI < parameters.length; minConsumedI++) {
|
||||
parameter = parameters[minConsumedI];
|
||||
if (parameter.getBinding().getBehavior(parameter) != BindingBehavior.PROVIDES) {
|
||||
suggestion.append(prefix);
|
||||
List<String> argSuggestions = parameter.getBinding().getSuggestions(parameter, consumed);
|
||||
switch (argSuggestions.size()) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
suggestion.append(argSuggestions.iterator().next());
|
||||
break;
|
||||
default:
|
||||
suggestion.setLength(0);
|
||||
suggestions.addAll(argSuggestions);
|
||||
break outer;
|
||||
|
||||
}
|
||||
consumed = "";
|
||||
prefix = " ";
|
||||
}
|
||||
}
|
||||
if (suggestion.length() != 0) suggestions.add(suggestion.toString());
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
}
|
||||
|
@ -191,9 +191,11 @@ public class BindingHelper implements Binding {
|
||||
char bracket = parameter.isOptional() ? '[' : '<';
|
||||
char endBracket = StringMan.getMatchingBracket(bracket);
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append("\u00A75");
|
||||
result.append(bracket);
|
||||
result.append("\u00A7r");
|
||||
if (parameter.getFlag() != null) {
|
||||
result.append('-').append(parameter.getFlag()).append(' ');
|
||||
result.append('-').append(parameter.getFlag()).append("\u00A75 \u00A7r");
|
||||
}
|
||||
result.append(parameter.getName());
|
||||
if (parameter.getDefaultValue() != null) {
|
||||
@ -203,7 +205,9 @@ public class BindingHelper implements Binding {
|
||||
if (range != null) {
|
||||
result.append('|').append(StringMan.prettyFormat(range.min())).append(",").append(StringMan.prettyFormat(range.max()));
|
||||
}
|
||||
result.append("\u00A75");
|
||||
result.append(endBracket);
|
||||
result.append("\u00A7r");
|
||||
return Collections.singletonList(result.toString());
|
||||
}
|
||||
return new ArrayList<>();
|
||||
|
@ -139,7 +139,7 @@ public class ContextArgumentStack implements ArgumentStack {
|
||||
*/
|
||||
@Override
|
||||
public String reset() {
|
||||
String value = context.getString(markedIndex, index - 1);
|
||||
String value = (index - 1 > markedIndex) ? context.getString(markedIndex, index - 1) : "";
|
||||
index = markedIndex;
|
||||
return value;
|
||||
}
|
||||
|
@ -28,7 +28,9 @@
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.thoughtworks.paranamer;
|
||||
package com.sk89q.worldedit.util.command.parametric;
|
||||
|
||||
import com.thoughtworks.paranamer.CachingParanamer;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -31,27 +31,8 @@ public class FunctionParametricCallable extends AParametricCallable {
|
||||
this.function = function;
|
||||
this.group = group;
|
||||
|
||||
List<String> paramNames = new ArrayList<>();
|
||||
List<String> typeStrings = new ArrayList<>();
|
||||
List<Type> types = new ArrayList<>();
|
||||
List<Object[]> paramParsables = new ArrayList<>();
|
||||
{
|
||||
boolean checkType = false;
|
||||
for (String argument : arguments) {
|
||||
if (checkType) {
|
||||
typeStrings.set(typeStrings.size() - 1, argument);
|
||||
} else {
|
||||
checkType = false;
|
||||
if (argument.equals("=")) {
|
||||
checkType = true;
|
||||
} else if (argument.length() == 1 && command.flags().contains(argument)) {
|
||||
typeStrings.add("java.lang.Boolean");
|
||||
paramNames.add(argument);
|
||||
} else {
|
||||
typeStrings.add("java.lang.String");
|
||||
paramNames.add(argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<Type, Binding> bindings = builder.getBindings();
|
||||
Map<String, Type> unqualified = new HashMap<>();
|
||||
for (Map.Entry<Type, Binding> entry : bindings.entrySet()) {
|
||||
@ -60,14 +41,46 @@ public class FunctionParametricCallable extends AParametricCallable {
|
||||
unqualified.put(typeStr, type);
|
||||
unqualified.put(typeStr.substring(typeStr.lastIndexOf('.') + 1), type);
|
||||
}
|
||||
for (String typeStr : typeStrings) {
|
||||
Type type = unqualified.get(typeStr);
|
||||
if (type == null) type = unqualified.get("java.lang.String");
|
||||
types.add(type);
|
||||
{
|
||||
Object[] param = null; // name | type | optional value
|
||||
boolean checkEq = false;
|
||||
int checkEqI = 0;
|
||||
for (int i = 0; i < arguments.size(); i++) {
|
||||
String arg = arguments.get(i);
|
||||
if (arg.equals("=")) {
|
||||
checkEqI++;
|
||||
checkEq = true;
|
||||
} else if (param == null || !checkEq) {
|
||||
if (param != null) paramParsables.add(param);
|
||||
param = new Object[3];
|
||||
param[0] = arg;
|
||||
if (arg.length() == 1 && command.flags().contains(arg)) {
|
||||
param[1] = Boolean.class;
|
||||
} else {
|
||||
param[1] = String.class;
|
||||
}
|
||||
param[2] = null;
|
||||
checkEqI = 0;
|
||||
checkEq = false;
|
||||
} else {
|
||||
if (checkEqI == 1) {
|
||||
param[1] = unqualified.getOrDefault(arg, String.class);
|
||||
checkEq = false;
|
||||
}
|
||||
else if (checkEqI == 2) {
|
||||
char c = arg.charAt(0);
|
||||
if (c == '\'' || c == '"') arg = arg.substring(1, arg.length() - 1);
|
||||
param[2] = arg;
|
||||
checkEqI = 0;
|
||||
checkEq = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (param != null) paramParsables.add(param);
|
||||
}
|
||||
}
|
||||
|
||||
parameters = new ParameterData[paramNames.size()];
|
||||
parameters = new ParameterData[paramParsables.size()];
|
||||
List<Parameter> userParameters = new ArrayList<Parameter>();
|
||||
|
||||
// This helps keep tracks of @Nullables that appear in the middle of a list
|
||||
@ -75,20 +88,25 @@ public class FunctionParametricCallable extends AParametricCallable {
|
||||
int numOptional = 0;
|
||||
//
|
||||
// Go through each parameter
|
||||
for (int i = 0; i < types.size(); i++) {
|
||||
Type type = types.get(i);
|
||||
for (int i = 0; i < paramParsables.size(); i++) {
|
||||
Object[] parsable = paramParsables.get(i);
|
||||
String paramName = (String) parsable[0];
|
||||
Type type = (Type) parsable[1];
|
||||
String optional = (String) parsable[2];
|
||||
|
||||
ParameterData parameter = new ParameterData();
|
||||
parameter.setType(type);
|
||||
parameter.setModifiers(new Annotation[0]);
|
||||
|
||||
String paramName = paramNames.get(i);
|
||||
boolean flag = paramName.length() == 1 && command.flags().contains(paramName);
|
||||
if (flag) {
|
||||
parameter.setFlag(paramName.charAt(0), type != boolean.class && type != Boolean.class);
|
||||
}
|
||||
|
||||
// TODO switch / Optional / Search for annotations /
|
||||
if (optional != null) {
|
||||
parameter.setOptional(true);
|
||||
if (!optional.equalsIgnoreCase("null")) parameter.setDefaultValue(new String[]{optional});
|
||||
}
|
||||
|
||||
parameter.setName(paramName);
|
||||
|
||||
@ -256,7 +274,6 @@ public class FunctionParametricCallable extends AParametricCallable {
|
||||
|
||||
// postInvoke handlers
|
||||
{
|
||||
|
||||
}
|
||||
return result;
|
||||
} catch (MissingParameterException e) {
|
||||
|
@ -45,7 +45,6 @@ import com.sk89q.worldedit.util.command.ProcessedCallable;
|
||||
import com.sk89q.worldedit.util.command.binding.PrimitiveBindings;
|
||||
import com.sk89q.worldedit.util.command.binding.StandardBindings;
|
||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||
import com.thoughtworks.paranamer.FaweParanamer;
|
||||
import com.thoughtworks.paranamer.Paranamer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
|
@ -146,7 +146,7 @@ public class StringArgumentStack implements ArgumentStack {
|
||||
*/
|
||||
@Override
|
||||
public String reset() {
|
||||
String value = context.getString(markedIndex, index - 1);
|
||||
String value = (index - 1 > markedIndex) ? context.getString(markedIndex, index - 1) : "";
|
||||
index = markedIndex;
|
||||
return value;
|
||||
}
|
||||
|
@ -20,25 +20,27 @@
|
||||
package com.sk89q.worldedit.world.block;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.command.SuggestInputParseException;
|
||||
import com.boydti.fawe.object.string.MutableCharSequence;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.TileEntityBlock;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.SingleBlockStateMask;
|
||||
import com.sk89q.worldedit.function.pattern.FawePattern;
|
||||
import com.sk89q.worldedit.registry.state.AbstractProperty;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* An immutable class that represents the state a block can be in.
|
||||
@ -60,7 +62,7 @@ public class BlockState implements BlockStateHolder<BlockState> {
|
||||
* @return BlockState
|
||||
*/
|
||||
@Deprecated
|
||||
public static BlockState get(int combinedId) {
|
||||
public static BlockState get(int combinedId) throws InputParseException {
|
||||
return BlockTypes.getFromStateId(combinedId).withStateId(combinedId);
|
||||
}
|
||||
|
||||
@ -69,7 +71,7 @@ public class BlockState implements BlockStateHolder<BlockState> {
|
||||
* @param state String e.g. minecraft:water[level=4]
|
||||
* @return BlockState
|
||||
*/
|
||||
public static BlockState get(String state) {
|
||||
public static BlockState get(String state) throws InputParseException {
|
||||
return get(null, state);
|
||||
}
|
||||
|
||||
@ -80,7 +82,7 @@ public class BlockState implements BlockStateHolder<BlockState> {
|
||||
* @param state String e.g. minecraft:water[level=4]
|
||||
* @return BlockState
|
||||
*/
|
||||
public static BlockState get(@Nullable BlockType type, String state) {
|
||||
public static BlockState get(@Nullable BlockType type, String state) throws InputParseException {
|
||||
return get(type, state, 0);
|
||||
}
|
||||
|
||||
@ -91,7 +93,7 @@ public class BlockState implements BlockStateHolder<BlockState> {
|
||||
* @param state String e.g. minecraft:water[level=4]
|
||||
* @return BlockState
|
||||
*/
|
||||
public static BlockState get(@Nullable BlockType type, String state, int propId) {
|
||||
public static BlockState get(@Nullable BlockType type, String state, int propId) throws InputParseException {
|
||||
int propStrStart = state.indexOf('[');
|
||||
if (type == null) {
|
||||
CharSequence key;
|
||||
@ -104,6 +106,14 @@ public class BlockState implements BlockStateHolder<BlockState> {
|
||||
key = charSequence;
|
||||
}
|
||||
type = BlockTypes.get(key);
|
||||
if (type == null) {
|
||||
String input = key.toString();
|
||||
throw new SuggestInputParseException("Unkown block for " + input, input, () -> Stream.of(BlockTypes.values)
|
||||
.filter(b -> b.getId().contains(input))
|
||||
.map(e1 -> e1.getId())
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
}
|
||||
if (propStrStart == -1) {
|
||||
return type.getDefaultState();
|
||||
@ -111,6 +121,7 @@ public class BlockState implements BlockStateHolder<BlockState> {
|
||||
|
||||
List<? extends Property> propList = type.getProperties();
|
||||
|
||||
if (state.charAt(state.length() - 1) != ']') state = state + "]";
|
||||
MutableCharSequence charSequence = MutableCharSequence.getTemporal();
|
||||
charSequence.setString(state);
|
||||
|
||||
@ -133,13 +144,36 @@ public class BlockState implements BlockStateHolder<BlockState> {
|
||||
switch (c) {
|
||||
case ']':
|
||||
case ',': {
|
||||
charSequence.setSubstring(last, i);
|
||||
if (property != null) {
|
||||
charSequence.setSubstring(last, i);
|
||||
int index = property.getIndexFor(charSequence);
|
||||
if (index == -1) {
|
||||
String input = charSequence.toString();
|
||||
List<Object> values = property.getValues();
|
||||
throw new SuggestInputParseException("No value: " + input + " for " + type, input, () ->
|
||||
values.stream()
|
||||
.map(v -> v.toString())
|
||||
.filter(v -> v.startsWith(input))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
stateId = property.modifyIndex(stateId, index);
|
||||
} else {
|
||||
Fawe.debug("Invalid property " + type + " | " + charSequence);
|
||||
// suggest
|
||||
PropertyKey key = PropertyKey.get(charSequence);
|
||||
if (key == null || !type.hasProperty(key)) {
|
||||
// Suggest property
|
||||
String input = charSequence.toString();
|
||||
BlockType finalType = type;
|
||||
throw new SuggestInputParseException("Invalid property " + type + " | " + input, input, () ->
|
||||
finalType.getProperties().stream()
|
||||
.map(p -> p.getName())
|
||||
.filter(p -> p.startsWith(input))
|
||||
.collect(Collectors.toList()));
|
||||
} else {
|
||||
throw new SuggestInputParseException("No operator for " + state, "", () -> Arrays.asList("="));
|
||||
}
|
||||
}
|
||||
property = null;
|
||||
last = i + 1;
|
||||
break;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.world.block;
|
||||
|
||||
import com.boydti.fawe.command.SuggestInputParseException;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
@ -41,6 +42,7 @@ import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Stores a list of common Block String IDs.
|
||||
@ -946,6 +948,7 @@ public enum BlockTypes implements BlockType {
|
||||
private static final Map<String, BlockTypes> $REGISTRY = new HashMap<>();
|
||||
private static int $LENGTH;
|
||||
public static final BlockTypes[] values;
|
||||
private static final Set<String> $NAMESPACES = new LinkedHashSet<String>();
|
||||
|
||||
static {
|
||||
try {
|
||||
@ -979,8 +982,9 @@ public enum BlockTypes implements BlockType {
|
||||
}
|
||||
}
|
||||
|
||||
public static BlockTypes parse(String input) throws InputParseException {
|
||||
input = input.toLowerCase();
|
||||
public static BlockTypes parse(final String type) throws InputParseException {
|
||||
final String inputLower = type.toLowerCase();
|
||||
String input = inputLower;
|
||||
|
||||
if (!input.split("\\[", 2)[0].contains(":")) input = "minecraft:" + input;
|
||||
BlockTypes result = $REGISTRY.get(input);
|
||||
@ -991,7 +995,12 @@ public enum BlockTypes implements BlockType {
|
||||
if (block != null) return block.getBlockType();
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (IndexOutOfBoundsException e) {}
|
||||
throw new InputParseException("Unkown block for " + input);
|
||||
|
||||
throw new SuggestInputParseException("Unkown block for " + inputLower, inputLower, () -> Stream.of(BlockTypes.values)
|
||||
.filter(b -> b.getId().contains(inputLower))
|
||||
.map(e1 -> e1.getId())
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
private static BlockTypes register(final String id) {
|
||||
@ -1014,9 +1023,15 @@ public enum BlockTypes implements BlockType {
|
||||
existing.init(id, internalId);
|
||||
if (typeName.startsWith("minecraft:")) $REGISTRY.put(typeName.substring(10), existing);
|
||||
$REGISTRY.put(typeName, existing);
|
||||
String nameSpace = typeName.substring(0, typeName.indexOf(':'));
|
||||
$NAMESPACES.add(nameSpace);
|
||||
return existing;
|
||||
}
|
||||
|
||||
public static Set<String> getNameSpaces() {
|
||||
return $NAMESPACES;
|
||||
}
|
||||
|
||||
public static final @Nullable BlockTypes get(final String id) {
|
||||
return $REGISTRY.get(id);
|
||||
}
|
||||
|
Reference in New Issue
Block a user