mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-12 08:08:34 +00:00
Feature/propagate diff and object cleanup (#1190)
* Feature/main/propagate diff annotations (#1187) * 25% done * More work * More work * 50% * More work * 75% * 100% & cleanup * Update adapters * Squish squash, applesauce commit275ba9bd84
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Sat Jul 17 01:10:20 2021 +0200 Update dependency com.comphenix.protocol:ProtocolLib to v4.7.0 (#1173) Co-authored-by: Renovate Bot <bot@renovateapp.com> commit9fd8984804
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Date: Sat Jul 17 01:09:29 2021 +0200 Update dependency org.checkerframework:checker-qual to v3.16.0 (#1184) Co-authored-by: Renovate Bot <bot@renovateapp.com> commit861fb45e5c
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 19:07:02 2021 +0100 Fix #1075 commit420c45a29a
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 18:48:21 2021 +0100 Entity removal should be on the main thread as we're just passing through rather than doing chunk operations - Fixes #1164 - Not working: butcher/remove history commit4d4db7dcd0
Author: SirYwell <hannesgreule@outlook.de> Date: Fri Jul 16 17:52:44 2021 +0200 Make sure leaves category is loaded for heightmaps (fixes #1176) commitc98f6e4f37
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 10:44:52 2021 +0100 Do not allow generation commands to generate outside selection commit2485f5eccc
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 10:43:15 2021 +0100 EditSession needs to override some Extent methods to ensure block changes are correctly set through the various extents Fixes #1152 commitd9418ec8ae
Author: dordsor21 <dordsor21@gmail.com> Date: Fri Jul 16 09:52:44 2021 +0100 Undo part of41073bb1a0
Fixes #1178 * Update Upstream fb1fb84 Fixed typo and grammar * We don't support custom heights yet * Casing inconsistency * Address a few comments * Address comments * Don't refactor to AP classpath * Document annotation style * Refactoring & shade cleanup * Address a few comments * More work * Resolve comments not being resolved yet * Feature/main/propagate diff annotations (#1187) (#1194) * Remove beta package, fix history packages, move classes out of object package * Resolve comments not being resolved yet * Remove beta package, fix history packages, move classes out of object package Co-authored-by: NotMyFault <mc.cache@web.de> * brushes should be under brush * More refactoring - Filters/processors should be in the same place and are related to extents - Transforms are in `extent.transform` in upstream * Move history classes under history * Update adapters Co-authored-by: dordsor21 <dordsor21@gmail.com>
This commit is contained in:
@ -0,0 +1,136 @@
|
||||
// TODO: Ping @MattBDev to reimplement 2020-02-04
|
||||
//package com.sk89q.worldedit.extension.factory;
|
||||
//
|
||||
//import com.boydti.fawe.command.FaweParser;
|
||||
//import com.boydti.fawe.command.SuggestInputParseException;
|
||||
//import com.boydti.fawe.object.extent.MultiTransform;
|
||||
//import com.boydti.fawe.object.extent.RandomTransform;
|
||||
//import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
//import com.boydti.fawe.object.random.TrueRandom;
|
||||
//import com.boydti.fawe.util.StringMan;
|
||||
//import com.google.common.collect.Iterables;
|
||||
//import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||
//import com.sk89q.worldedit.WorldEdit;
|
||||
////import com.sk89q.worldedit.command.TransformCommands;
|
||||
//import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
//import com.sk89q.worldedit.extension.input.NoMatchException;
|
||||
//import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
//import com.sk89q.worldedit.extension.platform.Actor;
|
||||
//import com.sk89q.worldedit.internal.expression.Expression;
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//
|
||||
//public class DefaultTransformParser extends FaweParser<ResettableExtent> {
|
||||
//
|
||||
// public DefaultTransformParser(WorldEdit worldEdit) {
|
||||
// super(worldEdit, "transforms");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public ResettableExtent parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
// if (input.isEmpty()) return null;
|
||||
//
|
||||
// List<Double> unionChances = new ArrayList<>();
|
||||
// List<Double> intersectionChances = new ArrayList<>();
|
||||
//
|
||||
// List<ResettableExtent> intersection = new ArrayList<>();
|
||||
// List<ResettableExtent> union = new ArrayList<>();
|
||||
// final CommandLocals locals = new CommandLocals();
|
||||
// Actor actor = context != null ? context.getActor() : null;
|
||||
// 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;
|
||||
// ResettableExtent transform;
|
||||
// double chance = 1;
|
||||
// if (command.isEmpty()) {
|
||||
// transform = parseFromInput(StringMan.join(entry.getValue(), ','), context);
|
||||
// } else {
|
||||
// List<String> args = entry.getValue();
|
||||
// String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " "));
|
||||
// try {
|
||||
// transform = parse(command + cmdArgs, context);
|
||||
// } catch (SuggestInputParseException rethrow) {
|
||||
// throw rethrow;
|
||||
// } catch (Throwable e) {
|
||||
// throw new NoMatchException("See: //transforms");
|
||||
// }
|
||||
// if (transform == null) {
|
||||
// // Legacy syntax
|
||||
// int percentIndex = command.indexOf('%');
|
||||
// if (percentIndex != -1) { // Legacy percent pattern
|
||||
// chance = Expression.compile(command.substring(0, percentIndex)).evaluate();
|
||||
// command = command.substring(percentIndex + 1);
|
||||
// if (!entry.getValue().isEmpty()) {
|
||||
// if (!command.isEmpty()) command += " ";
|
||||
// command += StringMan.join(entry.getValue(), " ");
|
||||
// }
|
||||
// transform = parseFromInput(command, context);
|
||||
// } else {
|
||||
// throw new NoMatchException("See: //transforms");
|
||||
// }
|
||||
// }
|
||||
// if (pe.and) { // &
|
||||
// intersectionChances.add(chance);
|
||||
// intersection.add(transform);
|
||||
// } else {
|
||||
// if (!intersection.isEmpty()) {
|
||||
// if (intersection.size() == 1) {
|
||||
// throw new InputParseException("Error, floating &");
|
||||
// }
|
||||
// MultiTransform multi = new MultiTransform();
|
||||
// double total = 0;
|
||||
// for (int i = 0; i < intersection.size(); i++) {
|
||||
// Double value = intersectionChances.get(i);
|
||||
// total += value;
|
||||
// multi.add(intersection.get(i), value);
|
||||
// }
|
||||
// union.add(multi);
|
||||
// unionChances.add(total);
|
||||
// intersection.clear();
|
||||
// intersectionChances.clear();
|
||||
// }
|
||||
// unionChances.add(chance);
|
||||
// union.add(transform);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } catch (Throwable e) {
|
||||
// throw new InputParseException(e.getMessage(), e);
|
||||
// }
|
||||
// if (!intersection.isEmpty()) {
|
||||
// if (intersection.size() == 1) {
|
||||
// throw new InputParseException("Error, floating &");
|
||||
// }
|
||||
// MultiTransform multi = new MultiTransform();
|
||||
// double total = 0;
|
||||
// for (int i = 0; i < intersection.size(); i++) {
|
||||
// Double value = intersectionChances.get(i);
|
||||
// total += value;
|
||||
// multi.add(intersection.get(i), value);
|
||||
// }
|
||||
// union.add(multi);
|
||||
// unionChances.add(total);
|
||||
// intersection.clear();
|
||||
// intersectionChances.clear();
|
||||
// }
|
||||
// if (union.isEmpty()) {
|
||||
// throw new NoMatchException("See: //transforms");
|
||||
// } else if (union.size() == 1) {
|
||||
// return union.get(0);
|
||||
// } else {
|
||||
// RandomTransform random = new RandomTransform(new TrueRandom());
|
||||
// for (int i = 0; i < union.size(); i++) {
|
||||
// random.add(union.get(i), unionChances.get(i));
|
||||
// }
|
||||
// return random;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
//}
|
@ -0,0 +1,150 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* A rich parser allows parsing of patterns and masks with extra arguments,
|
||||
* e.g. #simplex[scale][pattern].
|
||||
*
|
||||
* @param <E> the parse result.
|
||||
*/
|
||||
public abstract class RichParser<E> extends InputParser<E> {
|
||||
private final String[] prefixes;
|
||||
|
||||
/**
|
||||
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
|
||||
*
|
||||
* @param worldEdit the worldedit instance.
|
||||
* @param aliases the prefix of this parser result.
|
||||
*/
|
||||
protected RichParser(WorldEdit worldEdit, String... aliases) {
|
||||
super(worldEdit);
|
||||
Preconditions.checkArgument(aliases.length >= 1, "Aliases may not be empty");
|
||||
this.prefixes = aliases;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Predicate<String> validPrefix(String other) {
|
||||
return prefix -> {
|
||||
if (prefix.length() > other.length()) {
|
||||
return prefix.startsWith(other);
|
||||
}
|
||||
return other.startsWith(prefix);
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Function<String, Stream<? extends String>> extractArguments(String input) {
|
||||
return prefix -> {
|
||||
if (input.length() > prefix.length()) {
|
||||
// input already contains argument(s) -> extract them
|
||||
String[] strings = extractArguments(input.substring(prefix.length()), false);
|
||||
// rebuild the argument string without the last argument
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < strings.length - 1; i++) {
|
||||
builder.append('[').append(strings[i]).append(']');
|
||||
}
|
||||
String previous = prefix + builder;
|
||||
// read the suggestions for the last argument
|
||||
return getSuggestions(strings[strings.length - 1], strings.length - 1)
|
||||
.map(suggestion -> previous + "[" + suggestion);
|
||||
} else {
|
||||
return Stream.of(prefix);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return this.prefixes[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
return Arrays.stream(this.prefixes)
|
||||
.filter(validPrefix(input))
|
||||
.flatMap(extractArguments(input));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
for (String prefix : this.prefixes) {
|
||||
if (!input.startsWith(prefix)) {
|
||||
continue;
|
||||
}
|
||||
if (input.length() < prefix.length()) {
|
||||
continue;
|
||||
}
|
||||
String[] arguments = extractArguments(input.substring(prefix.length()), true);
|
||||
return parseFromInput(arguments, context);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream of suggestions for the argument at the given index.
|
||||
*
|
||||
* @param argumentInput the already provided input for the argument at the given index.
|
||||
* @param index the index of the argument to get suggestions for.
|
||||
* @return a stream of suggestions matching the given input for the argument at the given index.
|
||||
*/
|
||||
protected abstract Stream<String> getSuggestions(String argumentInput, int index);
|
||||
|
||||
/**
|
||||
* Parses the already split arguments.
|
||||
*
|
||||
* @param arguments the array of arguments that were split (can be empty).
|
||||
* @param context the context of this parsing process.
|
||||
* @return the resulting parsed type.
|
||||
* @throws InputParseException if the input couldn't be parsed correctly.
|
||||
*/
|
||||
protected abstract E parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException;
|
||||
|
||||
/**
|
||||
* Extracts arguments enclosed by {@code []} into an array.
|
||||
* Example: {@code [Hello][World]} results in a list containing {@code Hello} and {@code World}.
|
||||
*
|
||||
* @param input the input to extract arguments from.
|
||||
* @param requireClosing whether or not the extraction requires valid bracketing.
|
||||
* @return an array of extracted arguments.
|
||||
* @throws InputParseException if {@code requireClosing == true} and the count of [ != the count of ]
|
||||
*/
|
||||
protected String[] extractArguments(String input, boolean requireClosing) throws InputParseException {
|
||||
int open = 0; // the "level"
|
||||
int openIndex = 0;
|
||||
int i = 0;
|
||||
List<String> arguments = new ArrayList<>();
|
||||
for (; i < input.length(); i++) {
|
||||
if (input.charAt(i) == '[') {
|
||||
if (open++ == 0) {
|
||||
openIndex = i;
|
||||
}
|
||||
}
|
||||
if (input.charAt(i) == ']') {
|
||||
if (--open == 0) {
|
||||
arguments.add(input.substring(openIndex + 1, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!requireClosing && open > 0) {
|
||||
arguments.add(input.substring(openIndex + 1));
|
||||
}
|
||||
if (requireClosing && open != 0) {
|
||||
throw new InputParseException(Caption.of("fawe.error.invalid-bracketing", TextComponent.of("'[' or ']'?")));
|
||||
}
|
||||
return arguments.toArray(new String[0]);
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.fastasyncworldedit.core.function.mask.AdjacentAnyMask;
|
||||
import com.fastasyncworldedit.core.function.mask.AdjacentMask;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class AdjacentMaskParser extends RichParser<Mask> {
|
||||
|
||||
public AdjacentMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, "~");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
if (index == 0) {
|
||||
return worldEdit.getMaskFactory().getSuggestions(argumentInput).stream();
|
||||
} else if (index == 1 || index == 2) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mask parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
|
||||
if (arguments.length == 0) {
|
||||
return null;
|
||||
}
|
||||
Mask subMask = worldEdit.getMaskFactory().parseFromInput(arguments[0], context);
|
||||
int min = arguments.length > 1 ? Integer.parseInt(arguments[1]) : -1;
|
||||
int max = arguments.length > 2 ? Integer.parseInt(arguments[2]) : -1;
|
||||
if (min == -1 && max == -1) {
|
||||
min = 1;
|
||||
max = 8;
|
||||
} else if (max == -1) {
|
||||
max = min;
|
||||
}
|
||||
if (max >= 8 && min == 1) {
|
||||
return new AdjacentAnyMask(subMask);
|
||||
}
|
||||
return new AdjacentMask(subMask, min, max);
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.function.mask.AngleMask;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class AngleMaskParser extends RichParser<Mask> {
|
||||
|
||||
private final String[] flags = new String[]{"-o"};
|
||||
|
||||
public AngleMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, "/");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
if (index == 0 || index == 1) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
|
||||
} else if (index > 1 && index <= 1 + flags.length) {
|
||||
return Stream.of(flags);
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mask parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
|
||||
if (arguments.length < 2 || arguments.length > 2 + flags.length) {
|
||||
return null;
|
||||
}
|
||||
String minArg = arguments[0];
|
||||
String maxArg = arguments[1];
|
||||
boolean degree = minArg.endsWith("d");
|
||||
if (degree ^ maxArg.endsWith("d")) {
|
||||
throw new InputParseException(Caption.of("fawe.error.mask.angle"));
|
||||
}
|
||||
boolean overlay = false;
|
||||
if (arguments.length > 2) {
|
||||
for (int index = 2; index < 2 + flags.length; index++) {
|
||||
String flag = arguments[index];
|
||||
if (flag.equals("-o")) {
|
||||
overlay = true;
|
||||
} else {
|
||||
throw new InputParseException(Caption.of("fawe.error.invalid-flag",
|
||||
TextComponent.of(flag)));
|
||||
}
|
||||
}
|
||||
}
|
||||
double min;
|
||||
double max;
|
||||
if (degree) {
|
||||
double minDeg = Double.parseDouble(minArg.substring(0, minArg.length() - 1));
|
||||
double maxDeg = Double.parseDouble(maxArg.substring(0, maxArg.length() - 1));
|
||||
min = (Math.tan(minDeg * (Math.PI / 180)));
|
||||
max = (Math.tan(maxDeg * (Math.PI / 180)));
|
||||
} else {
|
||||
min = Double.parseDouble(minArg);
|
||||
max = Double.parseDouble(maxArg);
|
||||
}
|
||||
|
||||
return new AngleMask(context.getExtent(), min, max, overlay, 1);
|
||||
}
|
||||
}
|
@ -0,0 +1,189 @@
|
||||
// TODO: Ping @MattBDev to reimplement 2020-02-04
|
||||
//*
|
||||
//package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
//
|
||||
//import com.boydti.fawe.command.FaweParser;
|
||||
//import com.boydti.fawe.command.SuggestInputParseException;
|
||||
//import com.boydti.fawe.config.Caption;
|
||||
//import com.boydti.fawe.util.StringMan;
|
||||
//import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||
//import com.sk89q.worldedit.WorldEdit;
|
||||
//import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
//import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
//import com.sk89q.worldedit.extension.platform.Actor;
|
||||
//import com.sk89q.worldedit.extent.Extent;
|
||||
//import com.sk89q.worldedit.function.mask.BlockMaskBuilder;
|
||||
//import com.sk89q.worldedit.function.mask.Mask;
|
||||
//import com.sk89q.worldedit.function.mask.MaskIntersection;
|
||||
//import com.sk89q.worldedit.function.mask.MaskUnion;
|
||||
//import com.sk89q.worldedit.session.request.Request;
|
||||
//import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
//import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
//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 DefaultMaskParser extends FaweParser<Mask> {
|
||||
// public DefaultMaskParser(WorldEdit worldEdit) {
|
||||
// super(worldEdit, "masks");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
// 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<List<Mask>> masks = new ArrayList<>();
|
||||
// masks.add(new ArrayList<>());
|
||||
//
|
||||
// final CommandLocals locals = new CommandLocals();
|
||||
// Actor actor = context != null ? context.getActor() : null;
|
||||
// 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();
|
||||
// final String command = pe.input;
|
||||
// String full = pe.full;
|
||||
// Mask mask = null;
|
||||
// if (command.isEmpty()) {
|
||||
// mask = parseFromInput(StringMan.join(entry.getValue(), ','), context);
|
||||
// } else {
|
||||
// List<String> args = entry.getValue();
|
||||
// String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " "));
|
||||
// try {
|
||||
// mask = parse(command + cmdArgs, context);
|
||||
// } catch (SuggestInputParseException rethrow) {
|
||||
// throw rethrow;
|
||||
// } catch (Throwable e) {
|
||||
// // TODO NOT IMPLEMENTED
|
||||
//// 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 = "[" + 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());
|
||||
//// }
|
||||
//// });
|
||||
// }
|
||||
// if (mask == null) {
|
||||
// // Legacy patterns
|
||||
// char char0 = command.charAt(0);
|
||||
// boolean charMask = input.length() > 1 && input.charAt(1) != '[';
|
||||
// if (charMask && input.charAt(0) == '=') {
|
||||
// return parseFromInput(char0 + "[" + input.substring(1) + "]", context);
|
||||
// }
|
||||
// if (char0 == '#' || char0 == '?') {
|
||||
// // TODO NOT IMPLEMENTED
|
||||
//// throw new SuggestInputParseException(new NoMatchException("Unknown mask: " + full + ", See: //masks"), full,
|
||||
//// () -> {
|
||||
//// if (full.length() == 1) return new ArrayList<>(dispatcher.getPrimaryAliases());
|
||||
//// return dispatcher.getAliases().stream().filter(
|
||||
//// s -> s.startsWith(command.toLowerCase(Locale.ROOT))
|
||||
//// ).collect(Collectors.toList());
|
||||
//// }
|
||||
//// );
|
||||
// }
|
||||
// // 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;
|
||||
// }
|
||||
// case '|':
|
||||
// case '~':
|
||||
// case '<':
|
||||
// case '>':
|
||||
// case '!':
|
||||
// input = input.substring(input.indexOf(char0) + 1);
|
||||
// mask = parseFromInput(char0 + "[" + input + "]", context);
|
||||
// if (actor != null) {
|
||||
// actor.print(Caption.of("fawe.worldedit.help.command.clarifying.bracket", 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 (InputParseException ignored) {}
|
||||
// }
|
||||
// if (mask == null) {
|
||||
// context.setPreferringWildcard(false);
|
||||
// context.setRestricted(false);
|
||||
// BaseBlock block = worldEdit.getBlockFactory().parseFromInput(full, context);
|
||||
// builder.add(block);
|
||||
// mask = builder.build(extent);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (pe.and) {
|
||||
// masks.add(new ArrayList<>());
|
||||
// }
|
||||
// masks.get(masks.size() - 1).add(mask);
|
||||
// }
|
||||
// } catch (InputParseException rethrow) {
|
||||
// throw rethrow;
|
||||
// } catch (Throwable e) {
|
||||
// e.printStackTrace();
|
||||
// throw new InputParseException(e.getMessage(), e);
|
||||
// }
|
||||
// List<Mask> maskUnions = new ArrayList<>();
|
||||
// for (List<Mask> maskList : masks) {
|
||||
// if (maskList.size() == 1) {
|
||||
// maskUnions.add(maskList.get(0));
|
||||
// } else if (maskList.size() != 0) {
|
||||
// maskUnions.add(new MaskUnion(maskList));
|
||||
// }
|
||||
// }
|
||||
// if (maskUnions.size() == 1) {
|
||||
// return maskUnions.get(0);
|
||||
// } else if (maskUnions.size() != 0) {
|
||||
// return new MaskIntersection(maskUnions);
|
||||
// } else {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//}
|
@ -0,0 +1,71 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.function.mask.ExtremaMask;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ExtremaMaskParser extends RichParser<Mask> {
|
||||
|
||||
private final String[] flags = new String[]{"-o"};
|
||||
|
||||
public ExtremaMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, "#extrema");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
if (index == 0 || index == 1) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
|
||||
} else if (index > 1 && index <= 1 + flags.length) {
|
||||
return Stream.of(flags);
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mask parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
|
||||
if (arguments.length < 2 || arguments.length > 2 + flags.length) {
|
||||
return null;
|
||||
}
|
||||
String minArg = arguments[0];
|
||||
String maxArg = arguments[1];
|
||||
boolean degree = minArg.endsWith("d");
|
||||
if (degree ^ maxArg.endsWith("d")) {
|
||||
throw new InputParseException(Caption.of("fawe.error.mask.angle"));
|
||||
}
|
||||
double min;
|
||||
double max;
|
||||
boolean overlay = false;
|
||||
if (arguments.length > 2) {
|
||||
for (int index = 2; index < 2 + flags.length; index++) {
|
||||
String flag = arguments[index];
|
||||
if (flag.equals("-o")) {
|
||||
overlay = true;
|
||||
} else {
|
||||
throw new InputParseException(Caption.of("fawe.error.invalid-flag",
|
||||
TextComponent.of(flag)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (degree) {
|
||||
double minDeg = Double.parseDouble(minArg.substring(0, minArg.length() - 1));
|
||||
double maxDeg = Double.parseDouble(maxArg.substring(0, maxArg.length() - 1));
|
||||
min = (Math.tan(minDeg * (Math.PI / 180)));
|
||||
max = (Math.tan(maxDeg * (Math.PI / 180)));
|
||||
} else {
|
||||
min = Double.parseDouble(minArg);
|
||||
max = Double.parseDouble(maxArg);
|
||||
}
|
||||
|
||||
return new ExtremaMask(context.getExtent(), min, max, overlay, 4);
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FalseMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#false");
|
||||
|
||||
public FalseMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromSimpleInput(String input, ParserContext context) {
|
||||
return Masks.alwaysFalse();
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.fastasyncworldedit.core.function.mask.LiquidMask;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LiquidMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#liquid");
|
||||
|
||||
public LiquidMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromSimpleInput(String input, ParserContext context) {
|
||||
return new LiquidMask(context.getExtent());
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.function.mask.ROCAngleMask;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ROCAngleMaskParser extends RichParser<Mask> {
|
||||
|
||||
private final String[] flags = new String[]{"-o"};
|
||||
|
||||
public ROCAngleMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, "#roc");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
if (index == 0 || index == 1) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput).flatMap(s -> Stream.of(s, s + "d"));
|
||||
} else if (index > 1 && index <= 1 + flags.length) {
|
||||
return Stream.of(flags);
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mask parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
|
||||
if (arguments.length < 2 || arguments.length > 2 + flags.length) {
|
||||
return null;
|
||||
}
|
||||
String minArg = arguments[0];
|
||||
String maxArg = arguments[1];
|
||||
boolean degree = minArg.endsWith("d");
|
||||
if (degree ^ maxArg.endsWith("d")) {
|
||||
throw new InputParseException(Caption.of("fawe.error.mask.angle"));
|
||||
}
|
||||
double min;
|
||||
double max;
|
||||
boolean overlay = false;
|
||||
if (arguments.length > 2) {
|
||||
for (int index = 2; index < 2 + flags.length; index++) {
|
||||
String flag = arguments[index];
|
||||
if (flag.equals("-o")) {
|
||||
overlay = true;
|
||||
} else {
|
||||
throw new InputParseException(Caption.of("fawe.error.invalid-flag",
|
||||
TextComponent.of(flag)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (degree) {
|
||||
double minDeg = Double.parseDouble(minArg.substring(0, minArg.length() - 1));
|
||||
double maxDeg = Double.parseDouble(maxArg.substring(0, maxArg.length() - 1));
|
||||
min = (Math.tan(minDeg * (Math.PI / 180)));
|
||||
max = (Math.tan(maxDeg * (Math.PI / 180)));
|
||||
} else {
|
||||
min = Double.parseDouble(minArg);
|
||||
max = Double.parseDouble(maxArg);
|
||||
}
|
||||
|
||||
return new ROCAngleMask(context.getExtent(), min, max, overlay, 4);
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.fastasyncworldedit.core.function.mask.RadiusMask;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class RadiusMaskParser extends RichParser<Mask> {
|
||||
|
||||
public RadiusMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, "{");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
if (index == 0 || index == 1) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mask parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
|
||||
if (arguments.length < 2) {
|
||||
return null;
|
||||
}
|
||||
int min = Integer.parseInt(arguments[0]);
|
||||
int max = Integer.parseInt(arguments[1]);
|
||||
return new RadiusMask(min, max);
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.MaskIntersection;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
import com.sk89q.worldedit.function.mask.OffsetMask;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class RichOffsetMaskParser extends RichParser<Mask> {
|
||||
|
||||
/**
|
||||
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
|
||||
*
|
||||
* @param worldEdit the worldedit instance.
|
||||
*/
|
||||
public RichOffsetMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, "#offset");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
if (index < 3) {
|
||||
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
}
|
||||
if (index == 3) {
|
||||
return worldEdit.getMaskFactory().getSuggestions(argumentInput).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mask parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
|
||||
if (arguments.length != 4) {
|
||||
return null;
|
||||
}
|
||||
int x = Integer.parseInt(arguments[0]);
|
||||
int y = Integer.parseInt(arguments[1]);
|
||||
int z = Integer.parseInt(arguments[2]);
|
||||
Mask submask = worldEdit.getMaskFactory().parseFromInput(arguments[3], context);
|
||||
OffsetMask offsetMask = new OffsetMask(submask, BlockVector3.at(x, y, z));
|
||||
return new MaskIntersection(offsetMask, Masks.negate(submask));
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.fastasyncworldedit.core.function.mask.SimplexMask;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SimplexMaskParser extends RichParser<Mask> {
|
||||
private static final String SIMPLEX_PREFIX = "#simplex";
|
||||
|
||||
public SimplexMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, SIMPLEX_PREFIX);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
if (index < 3) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mask parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
|
||||
if (arguments.length != 3) {
|
||||
return null;
|
||||
}
|
||||
double scale = Double.parseDouble(arguments[0]);
|
||||
double min = Double.parseDouble(arguments[1]);
|
||||
double max = Double.parseDouble(arguments[2]);
|
||||
scale = 1d / Math.max(1d, scale);
|
||||
min = (min - 50d) / 50d;
|
||||
max = (max - 50d) / 50d;
|
||||
return new SimplexMask(scale, min, max);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.fastasyncworldedit.core.function.mask.SurfaceMask;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SurfaceMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#surface");
|
||||
|
||||
public SurfaceMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
|
||||
return new SurfaceMask(context.getExtent());
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TrueMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#true");
|
||||
|
||||
public TrueMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromSimpleInput(String input, ParserContext context) {
|
||||
return Masks.alwaysTrue();
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.fastasyncworldedit.core.function.mask.WallMask;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.MaskIntersection;
|
||||
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WallMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#wall");
|
||||
|
||||
public WallMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
|
||||
return new MaskIntersection(new ExistingBlockMask(context.getExtent()), new WallMask(new BlockMask(context.getExtent(), BlockTypes.AIR.getDefaultState().toBaseBlock()), 1, 8));
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.fastasyncworldedit.core.function.mask.XAxisMask;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class XAxisMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#xaxis");
|
||||
|
||||
public XAxisMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromSimpleInput(String input, ParserContext context) {
|
||||
return new XAxisMask(context.getExtent());
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.fastasyncworldedit.core.function.mask.YAxisMask;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class YAxisMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#yaxis");
|
||||
|
||||
public YAxisMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromSimpleInput(String input, ParserContext context) {
|
||||
return new YAxisMask(context.getExtent());
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.mask;
|
||||
|
||||
import com.fastasyncworldedit.core.function.mask.ZAxisMask;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ZAxisMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#zaxis");
|
||||
|
||||
public ZAxisMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromSimpleInput(String input, ParserContext context) {
|
||||
return new ZAxisMask();
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.function.pattern.BiomeApplyingPattern;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.NoMatchException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class BiomePatternParser extends RichParser<Pattern> {
|
||||
private final static String BIOME_PREFIX = "$";
|
||||
|
||||
/**
|
||||
* Create a new biome pattern parser.
|
||||
*
|
||||
* @param worldEdit the worldedit instance.
|
||||
*/
|
||||
public BiomePatternParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, "#biome");
|
||||
}
|
||||
|
||||
// overridden to provide $<biome> too
|
||||
@Override
|
||||
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
if (input.startsWith(BIOME_PREFIX)) {
|
||||
String biomeId = input.substring(1);
|
||||
BiomeType biomeType = BiomeTypes.get(biomeId);
|
||||
if (biomeType == null) {
|
||||
throw new NoMatchException(Caption.of("worldedit.error.unknown-biome", TextComponent.of(biomeId)));
|
||||
}
|
||||
return new BiomeApplyingPattern(context.requireExtent(), biomeType);
|
||||
} else {
|
||||
return super.parseFromInput(input, context);
|
||||
}
|
||||
}
|
||||
|
||||
// overridden to provide $<biome> too
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
if (input.startsWith(BIOME_PREFIX)) {
|
||||
return BiomeType.REGISTRY.getSuggestions(input.substring(1)).map(biome -> BIOME_PREFIX + biome);
|
||||
} else {
|
||||
return super.getSuggestions(input);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
if (index == 0) {
|
||||
return BiomeType.REGISTRY.getSuggestions(argumentInput);
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Pattern parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
|
||||
if (arguments.length != 1) {
|
||||
throw new InputParseException(Caption.of("fawe.error.invalid-arguments", TextComponent.of("#biome[<biome>]")));
|
||||
}
|
||||
BiomeType biomeType = BiomeTypes.get(arguments[0]);
|
||||
if (biomeType == null) {
|
||||
throw new NoMatchException(Caption.of("worldedit.error.unknown-biome", TextComponent.of(arguments[0])));
|
||||
}
|
||||
return new BiomeApplyingPattern(context.requireExtent(), biomeType);
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.function.pattern.BufferedPattern;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class BufferedPatternParser extends RichParser<Pattern> {
|
||||
|
||||
/**
|
||||
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
|
||||
*
|
||||
* @param worldEdit the worldedit instance.
|
||||
*/
|
||||
public BufferedPatternParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, "#buffer");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
if (index == 0) {
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Pattern parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
|
||||
if (arguments.length != 1) {
|
||||
throw new InputParseException(Caption.of("fawe.error.command.syntax",
|
||||
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone,dirt])")));
|
||||
}
|
||||
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(arguments[0], context);
|
||||
return new BufferedPattern(context.requireActor(), inner);
|
||||
}
|
||||
}
|
@ -0,0 +1,167 @@
|
||||
// TODO: Ping @MattBDev to reimplement (or remove because this class is stupid) 2020-02-04
|
||||
///*
|
||||
//package com.fastasyncworldedit.core.extension.factory.parser.pattern;
|
||||
//
|
||||
//import com.boydti.fawe.command.FaweParser;
|
||||
//import com.boydti.fawe.command.SuggestInputParseException;
|
||||
//import com.boydti.fawe.object.random.TrueRandom;
|
||||
//import com.boydti.fawe.util.StringMan;
|
||||
//import com.google.common.collect.Iterables;
|
||||
//import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||
//import com.sk89q.worldedit.WorldEdit;
|
||||
//import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
//import com.sk89q.worldedit.extension.input.NoMatchException;
|
||||
//import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
//import com.sk89q.worldedit.extension.platform.Actor;
|
||||
//import com.sk89q.worldedit.extension.platform.PlatformCommandManager;
|
||||
//import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
//import com.sk89q.worldedit.function.pattern.RandomPattern;
|
||||
//import com.sk89q.worldedit.internal.expression.Expression;
|
||||
//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 DefaultPatternParser extends FaweParser<Pattern> {
|
||||
//
|
||||
// public DefaultPatternParser(WorldEdit worldEdit) {
|
||||
// super(worldEdit, "patterns");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
// 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();
|
||||
// Actor actor = context != null ? context.getActor() : null;
|
||||
// if (actor != null) {
|
||||
// locals.put(Actor.class, actor);
|
||||
// }
|
||||
// try {
|
||||
// for (Map.Entry<ParseEntry, List<String>> entry : parse(input)) {
|
||||
// ParseEntry pe = entry.getKey();
|
||||
// final String command = pe.input;
|
||||
// String full = pe.full;
|
||||
// Pattern pattern = null;
|
||||
// double chance = 1;
|
||||
// if (command.isEmpty()) {
|
||||
// pattern = parseFromInput(StringMan.join(entry.getValue(), ','), context);
|
||||
// } else {
|
||||
// List<String> args = entry.getValue();
|
||||
// String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " "));
|
||||
// try {
|
||||
// pattern = parse(command + cmdArgs, context);
|
||||
// } catch (SuggestInputParseException rethrow) {
|
||||
// throw rethrow;
|
||||
// } catch (Throwable e) {
|
||||
// // TODO NOT IMPLEMENTED
|
||||
//// 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 = "[" + 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());
|
||||
//// }
|
||||
//// });
|
||||
// }
|
||||
// if (pattern == null) {
|
||||
// // Legacy patterns
|
||||
// char char0 = command.charAt(0);
|
||||
// boolean charMask = input.length() > 1 && input.charAt(1) != '[';
|
||||
// if (charMask && input.charAt(0) == '=') {
|
||||
// return parseFromInput(char0 + "[" + input.substring(1) + "]", context);
|
||||
// }
|
||||
// if (char0 == '#') {
|
||||
// // TODO NOT IMPLEMENTED
|
||||
//// throw new SuggestInputParseException(new NoMatchException("Unknown pattern: " + full + ", See: //patterns"), full,
|
||||
//// () -> {
|
||||
//// if (full.length() == 1) return new ArrayList<>(dispatcher.getPrimaryAliases());
|
||||
//// return dispatcher.getAliases().stream().filter(
|
||||
//// s -> s.startsWith(command.toLowerCase(Locale.ROOT))
|
||||
//// ).collect(Collectors.toList());
|
||||
//// }
|
||||
//// );
|
||||
// }
|
||||
//
|
||||
//
|
||||
// if (charMask) {
|
||||
// if (char0 == '$') {
|
||||
// String value = command.substring(1) + ((entry.getValue().isEmpty()) ? ""
|
||||
// : "[" + StringMan.join(entry.getValue(), "][") + "]");
|
||||
// if (value.contains(":")) {
|
||||
// if (value.charAt(0) == ':') {
|
||||
// value.replaceFirst(":", "");
|
||||
// }
|
||||
// value = value.replaceAll(":", "][");
|
||||
// }
|
||||
// pattern = parseFromInput(char0 + "[" + value + "]", context);
|
||||
// }
|
||||
// }
|
||||
// if (pattern == null) {
|
||||
// if (command.startsWith("[")) {
|
||||
// int end = command.lastIndexOf(']');
|
||||
// pattern = parseFromInput(command.substring(1, end == -1 ? command.length() : end), context);
|
||||
// } else {
|
||||
// int percentIndex = command.indexOf('%');
|
||||
// if (percentIndex != -1) { // Legacy percent pattern
|
||||
// chance = Expression.compile(command.substring(0, percentIndex)).evaluate();
|
||||
// String value = command.substring(percentIndex + 1);
|
||||
// if (!entry.getValue().isEmpty()) {
|
||||
// if (!value.isEmpty()) value += " ";
|
||||
// value += StringMan.join(entry.getValue(), " ");
|
||||
// }
|
||||
// pattern = parseFromInput(value, context);
|
||||
// } else { // legacy block pattern
|
||||
// try {
|
||||
// pattern = worldEdit.getBlockFactory().parseFromInput(pe.full, context);
|
||||
// } catch (NoMatchException e) {
|
||||
// throw new NoMatchException(e.getMessage() + " See: //patterns");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (pattern != null) {
|
||||
// patterns.add(pattern);
|
||||
// chances.add(chance);
|
||||
// }
|
||||
// }
|
||||
// } catch (InputParseException rethrow) {
|
||||
// throw rethrow;
|
||||
// } catch (Throwable e) {
|
||||
// e.printStackTrace();
|
||||
// throw new InputParseException(e.getMessage(), e);
|
||||
// }
|
||||
// if (patterns.isEmpty()) {
|
||||
// return null;
|
||||
// }
|
||||
// if (patterns.size() == 1) {
|
||||
// return patterns.get(0);
|
||||
// }
|
||||
// RandomPattern random = new RandomPattern(new TrueRandom());
|
||||
// for (int i = 0; i < patterns.size(); i++) {
|
||||
// random.add(patterns.get(i), chances.get(i));
|
||||
// }
|
||||
// return random;
|
||||
// }
|
||||
//}
|
@ -0,0 +1,29 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
|
||||
|
||||
import com.fastasyncworldedit.core.function.pattern.ExistingPattern;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.internal.registry.SimpleInputParser;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ExistingPatternParser extends SimpleInputParser<Pattern> {
|
||||
private final List<String> aliases = Collections.singletonList("#existing");
|
||||
|
||||
public ExistingPatternParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return this.aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pattern parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
|
||||
return new ExistingPattern(context.requireExtent());
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.function.pattern.Linear2DBlockPattern;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.pattern.RandomPattern;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Linear2DPatternParser extends RichParser<Pattern> {
|
||||
|
||||
/**
|
||||
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
|
||||
*
|
||||
* @param worldEdit the worldedit instance.
|
||||
*/
|
||||
public Linear2DPatternParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, "#linear2d", "#l2d");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
case 1:
|
||||
case 2:
|
||||
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
default:
|
||||
return Stream.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Pattern parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
|
||||
if (arguments.length == 0 || arguments.length > 3) {
|
||||
throw new InputParseException(Caption.of("fawe.error.command.syntax",
|
||||
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone,dirt])")));
|
||||
}
|
||||
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(arguments[0], context);
|
||||
if (inner instanceof BlockStateHolder) {
|
||||
return inner;
|
||||
}
|
||||
int xScale = 1;
|
||||
int zScale = 1;
|
||||
if (arguments.length > 1) {
|
||||
xScale = Integer.parseInt(arguments[1]);
|
||||
Preconditions.checkArgument(xScale != 0);
|
||||
}
|
||||
if (arguments.length > 2) {
|
||||
zScale = Integer.parseInt(arguments[2]);
|
||||
Preconditions.checkArgument(zScale != 0);
|
||||
}
|
||||
if (inner instanceof RandomPattern) {
|
||||
Set<Pattern> patterns = ((RandomPattern) inner).getPatterns();
|
||||
return new Linear2DBlockPattern(patterns.toArray(new Pattern[0]), xScale, zScale);
|
||||
}
|
||||
throw new InputParseException(TextComponent.of("Pattern " + inner.getClass().getSimpleName()
|
||||
+ " cannot be used with " + getPrefix()));
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.function.pattern.Linear3DBlockPattern;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.pattern.RandomPattern;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Linear3DPatternParser extends RichParser<Pattern> {
|
||||
|
||||
/**
|
||||
* Create a new rich parser with a defined prefix for the result, e.g. {@code #simplex}.
|
||||
*
|
||||
* @param worldEdit the worldedit instance.
|
||||
*/
|
||||
public Linear3DPatternParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, "#linear3d", "#l3d");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return this.worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
return SuggestionHelper.suggestPositiveIntegers(argumentInput);
|
||||
default:
|
||||
return Stream.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Pattern parseFromInput(@NotNull String[] arguments, ParserContext context) throws InputParseException {
|
||||
if (arguments.length == 0 || arguments.length > 4) {
|
||||
throw new InputParseException(Caption.of("fawe.error.command.syntax",
|
||||
TextComponent.of(getPrefix() + "[pattern] (e.g. " + getPrefix() + "[stone,dirt])")));
|
||||
}
|
||||
Pattern inner = this.worldEdit.getPatternFactory().parseFromInput(arguments[0], context);
|
||||
if (inner instanceof BlockStateHolder) {
|
||||
return inner;
|
||||
}
|
||||
int xScale = 1;
|
||||
int yScale = 1;
|
||||
int zScale = 1;
|
||||
if (arguments.length > 1) {
|
||||
xScale = Integer.parseInt(arguments[1]);
|
||||
Preconditions.checkArgument(xScale != 0);
|
||||
}
|
||||
if (arguments.length > 2) {
|
||||
yScale = Integer.parseInt(arguments[2]);
|
||||
Preconditions.checkArgument(yScale != 0);
|
||||
}
|
||||
if (arguments.length > 3) {
|
||||
zScale = Integer.parseInt(arguments[3]);
|
||||
Preconditions.checkArgument(zScale != 0);
|
||||
}
|
||||
if (inner instanceof RandomPattern) {
|
||||
Set<Pattern> patterns = ((RandomPattern) inner).getPatterns();
|
||||
return new Linear3DBlockPattern(patterns.toArray(new Pattern[0]), xScale, yScale,zScale);
|
||||
}
|
||||
throw new InputParseException(TextComponent.of("Pattern " + inner.getClass().getSimpleName()
|
||||
+ " cannot be used with " + getPrefix()));
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.math.random.NoiseRandom;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.fastasyncworldedit.core.extension.factory.parser.RichParser;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.pattern.RandomPattern;
|
||||
import com.sk89q.worldedit.math.noise.NoiseGenerator;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public abstract class NoisePatternParser extends RichParser<Pattern> {
|
||||
|
||||
private final String name;
|
||||
private final Supplier<NoiseGenerator> generatorSupplier;
|
||||
|
||||
/**
|
||||
* Create a new noise parser with a defined name, e.g. {@code #simplex}.
|
||||
*
|
||||
* @param worldEdit the worldedit instance.
|
||||
* @param name the name of this noise.
|
||||
* @param generatorSupplier the supplier to get a {@link NoiseGenerator} instance from.
|
||||
*/
|
||||
protected NoisePatternParser(WorldEdit worldEdit, String name, Supplier<NoiseGenerator> generatorSupplier) {
|
||||
super(worldEdit, '#' + name);
|
||||
this.name = name;
|
||||
this.generatorSupplier = generatorSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<String> getSuggestions(String argumentInput, int index) {
|
||||
if (index == 0) {
|
||||
return SuggestionHelper.suggestPositiveDoubles(argumentInput);
|
||||
}
|
||||
if (index == 1) {
|
||||
return worldEdit.getPatternFactory().getSuggestions(argumentInput).stream();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Pattern parseFromInput(@NotNull String[] arguments, ParserContext context) {
|
||||
if (arguments.length != 2) {
|
||||
throw new InputParseException(Caption.of("fawe.error.command.syntax",
|
||||
TextComponent.of(getPrefix() + "[scale][pattern] (e.g. " + getPrefix() + "[5][dirt,stone])")));
|
||||
}
|
||||
double scale = parseScale(arguments[0]);
|
||||
Pattern inner = worldEdit.getPatternFactory().parseFromInput(arguments[1], context);
|
||||
if (inner instanceof RandomPattern) {
|
||||
return new RandomPattern(new NoiseRandom(this.generatorSupplier.get(), scale), (RandomPattern) inner);
|
||||
} else if (inner instanceof BlockStateHolder) {
|
||||
return inner; // single blocks won't have any impact on how a noise behaves
|
||||
} else {
|
||||
throw new InputParseException(TextComponent.of("Pattern " + inner.getClass().getSimpleName()
|
||||
+ " cannot be used with #" + this.name));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the given argument to match the requirements of the noise generator.
|
||||
*
|
||||
* @param argument the parsed scale argument.
|
||||
* @return the modified scale.
|
||||
*/
|
||||
protected double parseScale(String argument) {
|
||||
double scale = Double.parseDouble(argument);
|
||||
return 1d / Math.max(1, scale);
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.math.noise.PerlinNoise;
|
||||
|
||||
public class PerlinPatternParser extends NoisePatternParser {
|
||||
private static final String PERLIN_NAME = "perlin";
|
||||
|
||||
/**
|
||||
* Create a new perlin noise parser.
|
||||
*
|
||||
* @param worldEdit the worldedit instance.
|
||||
*/
|
||||
public PerlinPatternParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, PERLIN_NAME, PerlinNoise::new);
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.sk89q.util.StringUtil;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.pattern.RandomPattern;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class RandomPatternParser extends InputParser<Pattern> {
|
||||
|
||||
public RandomPatternParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
List<String> patterns = StringUtil.split(input, ',', '[', ']');
|
||||
/*String[] splits = input.split(",", -1);
|
||||
List<String> patterns = StringUtil.parseListInQuotes(splits, ',', '[', ']', true);*/
|
||||
if (patterns.size() == 1) {
|
||||
return Stream.empty();
|
||||
}
|
||||
// get suggestions for the last token only
|
||||
String token = patterns.get(patterns.size() - 1);
|
||||
String previous = String.join(",", patterns.subList(0, patterns.size() - 1));
|
||||
if (token.matches("[0-9]+(\\.[0-9]*)?%.*")) {
|
||||
String[] p = token.split("%");
|
||||
|
||||
if (p.length < 2) {
|
||||
return Stream.empty();
|
||||
} else {
|
||||
token = p[1];
|
||||
}
|
||||
}
|
||||
final List<String> innerSuggestions = worldEdit.getPatternFactory().getSuggestions(token);
|
||||
return innerSuggestions.stream().map(s -> previous + "," + s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
RandomPattern randomPattern = new RandomPattern();
|
||||
|
||||
List<String> patterns = StringUtil.split(input, ',', '[', ']');
|
||||
/*String[] splits = input.split(",", -1);
|
||||
List<String> patterns = StringUtil.parseListInQuotes(splits, ',', '[', ']', true);*/
|
||||
if (patterns.size() == 1) {
|
||||
return null; // let a 'single'-pattern parser handle it
|
||||
}
|
||||
for (String token : patterns) {
|
||||
double chance;
|
||||
Pattern innerPattern;
|
||||
|
||||
// Parse special percentage syntax
|
||||
if (token.matches("[0-9]+(\\.[0-9]*)?%.*")) {
|
||||
String[] p = token.split("%", 2);
|
||||
|
||||
if (p.length < 2) {
|
||||
throw new InputParseException(Caption.of("worldedit.error.parser.missing-random-type", TextComponent.of(input)));
|
||||
} else {
|
||||
chance = Double.parseDouble(p[0]);
|
||||
innerPattern = worldEdit.getPatternFactory().parseFromInput(p[1], context);
|
||||
}
|
||||
} else {
|
||||
chance = 1;
|
||||
innerPattern = worldEdit.getPatternFactory().parseFromInput(token, context);
|
||||
}
|
||||
|
||||
randomPattern.add(innerPattern, chance);
|
||||
}
|
||||
|
||||
return randomPattern;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.math.noise.RidgedMultiFractalNoise;
|
||||
|
||||
public class RidgedMultiFractalPatternParser extends NoisePatternParser {
|
||||
|
||||
private static final String RIDGED_MULTI_FRACTAL_NAME = "rmf";
|
||||
|
||||
/**
|
||||
* Create a new ridged multi fractal noise parser.
|
||||
*
|
||||
* @param worldEdit the worldedit instance.
|
||||
*/
|
||||
public RidgedMultiFractalPatternParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, RIDGED_MULTI_FRACTAL_NAME, RidgedMultiFractalNoise::new);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.fastasyncworldedit.core.math.random.SimplexNoiseGenerator;
|
||||
|
||||
public class SimplexPatternParser extends NoisePatternParser {
|
||||
private static final String SIMPLEX_NAME = "simplex";
|
||||
|
||||
public SimplexPatternParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, SIMPLEX_NAME, SimplexNoiseGenerator::new);
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.fastasyncworldedit.core.extension.factory.parser.pattern;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.math.noise.VoronoiNoise;
|
||||
|
||||
public class VoronoiPatternParser extends NoisePatternParser {
|
||||
|
||||
private static final String VORONOI_NAME = "voronoi";
|
||||
|
||||
/**
|
||||
* Create a new voronoi noise parser.
|
||||
*
|
||||
* @param worldEdit the worldedit instance.
|
||||
*/
|
||||
public VoronoiPatternParser(WorldEdit worldEdit) {
|
||||
super(worldEdit, VORONOI_NAME, VoronoiNoise::new);
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.fastasyncworldedit.core.extension.platform.binding;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Binding {
|
||||
String value() default "";
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
package com.fastasyncworldedit.core.extension.platform.binding;
|
||||
|
||||
import com.fastasyncworldedit.core.util.StringMan;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.enginehub.piston.CommandManager;
|
||||
import org.enginehub.piston.converter.ArgumentConverter;
|
||||
import org.enginehub.piston.converter.ConversionResult;
|
||||
import org.enginehub.piston.converter.FailedConversion;
|
||||
import org.enginehub.piston.converter.SuccessfulConversion;
|
||||
import org.enginehub.piston.exception.StopExecutionException;
|
||||
import org.enginehub.piston.inject.InjectedValueAccess;
|
||||
import org.enginehub.piston.inject.InjectedValueStore;
|
||||
import org.enginehub.piston.inject.Key;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Bindings {
|
||||
|
||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||
|
||||
private final WorldEdit worldEdit;
|
||||
|
||||
public Bindings(WorldEdit worldEdit) {
|
||||
this.worldEdit = worldEdit;
|
||||
}
|
||||
|
||||
public WorldEdit getWorldEdit() {
|
||||
return worldEdit;
|
||||
}
|
||||
|
||||
public void register(InjectedValueStore store, CommandManager manager) {
|
||||
for (Method method : getClass().getDeclaredMethods()) {
|
||||
register(method, store, manager);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean register(Method method, InjectedValueStore store, CommandManager manager) {
|
||||
// Check that it has the binding
|
||||
Binding binding = method.getAnnotation(Binding.class);
|
||||
if (binding == null) {
|
||||
return false;
|
||||
}
|
||||
Annotation[] annotations = method.getAnnotations();
|
||||
|
||||
// Get the key
|
||||
Class<?> ret = method.getReturnType();
|
||||
Key key;
|
||||
if ( annotations.length == 1) {
|
||||
key = Key.of(ret);
|
||||
} else if (annotations.length == 2) {
|
||||
Annotation annotation = annotations[0] == binding ? annotations[1] : annotations[0];
|
||||
key = Key.of(ret, annotation);
|
||||
} else {
|
||||
LOGGER.debug("Cannot annotate: " + method + " with " + StringMan.getString(annotations));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the provided parameters
|
||||
Class<?>[] params = method.getParameterTypes();
|
||||
Annotation[][] paramAnns = method.getParameterAnnotations();
|
||||
Function<InjectedValueAccess, Object>[] argsFunc = new Function[params.length];
|
||||
|
||||
boolean provide = true;
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
Class<?> param = params[i];
|
||||
if (param != String.class) {
|
||||
Annotation[] paramAnn = paramAnns[i];
|
||||
Key paramKey;
|
||||
if (paramAnn.length == 1) {
|
||||
paramKey = Key.of(param, paramAnn[0]);
|
||||
} else if (paramAnn.length == 0) {
|
||||
paramKey = Key.of(param);
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Only one annotation is permitted for " + method);
|
||||
}
|
||||
argsFunc[i] = v -> v.injectedValue(paramKey);
|
||||
} else if (provide) {
|
||||
provide = false;
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Only one argument is allowed");
|
||||
}
|
||||
}
|
||||
|
||||
// If the method provides all parameters
|
||||
if (provide) {
|
||||
store.injectValue(key, access -> Optional.of(invoke(null, argsFunc, access, method)));
|
||||
} else { // If the method consumes a String argument
|
||||
manager.registerConverter(key, new ArgumentConverter<Object>() {
|
||||
@Override
|
||||
public Component describeAcceptableArguments() {
|
||||
return TextComponent.of(binding.value());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversionResult<Object> convert(String s, InjectedValueAccess access) {
|
||||
Object o = invoke(s, argsFunc, access, method);
|
||||
if (o == null) {
|
||||
return FailedConversion.from(new NullPointerException());
|
||||
}
|
||||
return SuccessfulConversion.fromSingle(o);
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private Object invoke(String arg, Function<InjectedValueAccess, Object>[] argsFunc, InjectedValueAccess access, Method method) {
|
||||
try {
|
||||
Object[] args = new Object[argsFunc.length];
|
||||
for (int i = 0; i < argsFunc.length; i++) {
|
||||
Function<InjectedValueAccess, Object> func = argsFunc[i];
|
||||
if (func != null) {
|
||||
Optional optional = (Optional) func.apply(access);
|
||||
args[i] = optional.get();
|
||||
} else {
|
||||
args[i] = arg;
|
||||
}
|
||||
}
|
||||
return method.invoke(this, args);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
if (!(e.getCause() instanceof StopExecutionException)) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.fastasyncworldedit.core.extension.platform.binding;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
|
||||
public class CommandBindings extends Bindings {
|
||||
|
||||
public CommandBindings(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
}
|
@ -0,0 +1,161 @@
|
||||
package com.fastasyncworldedit.core.extension.platform.binding;
|
||||
|
||||
import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.util.MainUtil;
|
||||
import com.fastasyncworldedit.core.util.image.ImageUtil;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.annotation.Confirm;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.NoMatchException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.PlatformCommandManager;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.internal.annotation.Selection;
|
||||
import com.sk89q.worldedit.command.util.annotation.Time;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Identifiable;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import org.enginehub.piston.inject.InjectedValueAccess;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class ConsumeBindings extends Bindings {
|
||||
private final PlatformCommandManager manager;
|
||||
|
||||
public ConsumeBindings(WorldEdit worldEdit, PlatformCommandManager manager) {
|
||||
super(worldEdit);
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Time
|
||||
@Binding
|
||||
public Long time(Actor actor, String argument) {
|
||||
return MainUtil.timeToSec(argument) * 1000;
|
||||
}
|
||||
|
||||
@Binding
|
||||
@Confirm(Confirm.Processor.REGION)
|
||||
public int regionMultiple(Actor actor, InjectedValueAccess context, @Selection Region region, String argument) {
|
||||
int times = (int) Expression.compile(argument).evaluate();
|
||||
return Confirm.Processor.REGION.check(actor, context, times);
|
||||
}
|
||||
|
||||
@Binding
|
||||
@Confirm(Confirm.Processor.RADIUS)
|
||||
public Integer radiusInteger(Actor actor, InjectedValueAccess context, String argument) {
|
||||
int times = (int) Expression.compile(argument).evaluate();
|
||||
return Confirm.Processor.RADIUS.check(actor, context, times);
|
||||
}
|
||||
|
||||
@Binding
|
||||
@Confirm(Confirm.Processor.LIMIT)
|
||||
public Integer limitInteger(Actor actor, InjectedValueAccess context, String argument) {
|
||||
int times = (int) Expression.compile(argument).evaluate();
|
||||
return Confirm.Processor.LIMIT.check(actor, context, times);
|
||||
}
|
||||
|
||||
@Binding
|
||||
@Confirm(Confirm.Processor.RADIUS)
|
||||
public Double radiusDouble(Actor actor, InjectedValueAccess context, String argument) {
|
||||
double times = Expression.compile(argument).evaluate();
|
||||
return Confirm.Processor.RADIUS.check(actor, context, times);
|
||||
}
|
||||
|
||||
@Binding
|
||||
@Confirm(Confirm.Processor.LIMIT)
|
||||
public Double limitDouble(Actor actor, InjectedValueAccess context, String argument) {
|
||||
double times = Expression.compile(argument).evaluate();
|
||||
return Confirm.Processor.LIMIT.check(actor, context, times);
|
||||
}
|
||||
|
||||
@Binding
|
||||
@Confirm(Confirm.Processor.RADIUS)
|
||||
public BlockVector2 radiusVec2(Actor actor, InjectedValueAccess context, String argument) {
|
||||
BlockVector2 radius = manager.parseConverter(argument, context, BlockVector2.class);
|
||||
double length = radius.length();
|
||||
Confirm.Processor.RADIUS.check(actor, context, length);
|
||||
return radius;
|
||||
}
|
||||
|
||||
@Binding
|
||||
@Confirm(Confirm.Processor.RADIUS)
|
||||
public BlockVector3 radiusVec3(Actor actor, InjectedValueAccess context, String argument) {
|
||||
BlockVector3 radius = manager.parseConverter(argument, context, BlockVector3.class);
|
||||
double length = radius.length();
|
||||
Confirm.Processor.RADIUS.check(actor, context, length);
|
||||
return radius;
|
||||
}
|
||||
|
||||
@Binding
|
||||
public UUID playerUUID(Actor actor, String argument) {
|
||||
if (argument.equals("me")) {
|
||||
return actor.getUniqueId();
|
||||
}
|
||||
if (argument.equals("*")) {
|
||||
return Identifiable.EVERYONE;
|
||||
}
|
||||
if (argument.equalsIgnoreCase("console") || argument.equalsIgnoreCase("server")) {
|
||||
return Identifiable.CONSOLE;
|
||||
}
|
||||
UUID uuid;
|
||||
if (argument.length() > 16) {
|
||||
uuid = UUID.fromString(argument);
|
||||
} else {
|
||||
uuid = Fawe.imp().getUUID(argument);
|
||||
}
|
||||
if (uuid == null) {
|
||||
throw new InputParseException(Caption.of("fawe.error.player.not.found", TextComponent.of(argument)));
|
||||
}
|
||||
return uuid;
|
||||
}
|
||||
|
||||
|
||||
@Binding
|
||||
public ProvideBindings.ImageUri getImage(String argument) {
|
||||
return new ProvideBindings.ImageUri(ImageUtil.getImageURI(argument));
|
||||
}
|
||||
|
||||
@Binding
|
||||
public BlockType blockType(Actor actor, String argument) {
|
||||
return blockState(actor, argument).getBlockType();
|
||||
}
|
||||
|
||||
@Binding
|
||||
public BlockStateHolder blockStateHolder(Actor actor, String argument) {
|
||||
return blockState(actor, argument);
|
||||
}
|
||||
|
||||
@Binding
|
||||
public BlockState blockState(Actor actor, String argument) {
|
||||
return baseBlock(actor, argument).toBlockState();
|
||||
}
|
||||
|
||||
@Binding
|
||||
public BaseBlock baseBlock(Actor actor, String argument) {
|
||||
ParserContext parserContext = new ParserContext();
|
||||
parserContext.setActor(actor);
|
||||
if (actor instanceof Entity) {
|
||||
Extent extent = ((Entity) actor).getExtent();
|
||||
if (extent instanceof World) {
|
||||
parserContext.setWorld((World) extent);
|
||||
}
|
||||
}
|
||||
parserContext.setSession(getWorldEdit().getSessionManager().get(actor));
|
||||
try {
|
||||
return getWorldEdit().getBlockFactory().parseFromInput(argument, parserContext);
|
||||
} catch (NoMatchException e) {
|
||||
throw new InputParseException(Caption.of(e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,245 @@
|
||||
package com.fastasyncworldedit.core.extension.platform.binding;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.internal.expression.EvaluationException;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector2;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
|
||||
import java.util.Locale;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class PrimitiveBindings extends Bindings {
|
||||
public PrimitiveBindings(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
/*
|
||||
Parsers
|
||||
*/
|
||||
@Binding
|
||||
public Expression getExpression(String argument) throws ExpressionException {
|
||||
try {
|
||||
Expression expression = Expression.compile(argument);
|
||||
expression.optimize();
|
||||
return expression;
|
||||
} catch (EvaluationException e) {
|
||||
throw new InputParseException(String.format(
|
||||
"Expected '%s' to be a valid number (or a valid mathematical expression)", argument));
|
||||
} catch (ExpressionException e) {
|
||||
throw new InputParseException(String.format(
|
||||
"Expected '%s' to be a number or valid math expression (error: %s)", argument, e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Ping @MattBDev to reimplement 2020-02-04
|
||||
//
|
||||
// /**
|
||||
// * Gets an {@link Extent} from a {@link Binding}.
|
||||
// *
|
||||
// * @param argument the context
|
||||
// * @return an extent
|
||||
// * @throws InputParseException on other error
|
||||
// */
|
||||
// @Binding
|
||||
// public ResettableExtent getResettableExtent(Actor actor, String argument) throws InputParseException {
|
||||
// if (argument.equalsIgnoreCase("#null")) {
|
||||
// return new NullExtent();
|
||||
// }
|
||||
// DefaultTransformParser parser = Fawe.get().getTransformParser();
|
||||
// ParserContext parserContext = new ParserContext();
|
||||
// if (actor instanceof Entity) {
|
||||
// Extent extent = ((Entity) actor).getExtent();
|
||||
// if (extent instanceof World) {
|
||||
// parserContext.setWorld((World) extent);
|
||||
// }
|
||||
// }
|
||||
// parserContext.setSession(WorldEdit.getInstance().getSessionManager().get(actor));
|
||||
// return parser.parseFromInput(argument, parserContext);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Gets a type from a {@link Binding}.
|
||||
*
|
||||
* @param argument the context
|
||||
* @return the requested type
|
||||
* @throws InputParseException on error
|
||||
*/
|
||||
@Binding
|
||||
public Boolean getBoolean(String argument) {
|
||||
switch (argument.toLowerCase(Locale.ROOT)) {
|
||||
case "":
|
||||
throw new InputParseException(Caption.of("fawe.error.input-parser-exception"));
|
||||
case "true":
|
||||
case "yes":
|
||||
case "on":
|
||||
case "y":
|
||||
case "1":
|
||||
case "t":
|
||||
return true;
|
||||
case "false":
|
||||
case "no":
|
||||
case "off":
|
||||
case "f":
|
||||
case "n":
|
||||
case "0":
|
||||
return false;
|
||||
default:
|
||||
throw new InputParseException(Caption.of("fawe.error.invalid-boolean", TextComponent.of(argument)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a type from a {@link Binding}.
|
||||
*
|
||||
* @param argument the context
|
||||
* @return the requested type
|
||||
* @throws InputParseException on error
|
||||
*/
|
||||
@Binding
|
||||
public Vector3 getVector3(String argument) {
|
||||
String[] radii = argument.split(",");
|
||||
final double radiusX;
|
||||
final double radiusY;
|
||||
final double radiusZ;
|
||||
switch (radii.length) {
|
||||
case 1:
|
||||
radiusX = radiusY = radiusZ = PrimitiveBindings.parseNumericInput(radii[0]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
radiusX = PrimitiveBindings.parseNumericInput(radii[0]);
|
||||
radiusY = PrimitiveBindings.parseNumericInput(radii[1]);
|
||||
radiusZ = PrimitiveBindings.parseNumericInput(radii[2]);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InputParseException("You must either specify 1 or 3 radius values.");
|
||||
}
|
||||
return Vector3.at(radiusX, radiusY, radiusZ);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a type from a {@link Binding}.
|
||||
*
|
||||
* @param argument the context
|
||||
* @return the requested type
|
||||
* @throws InputParseException on error
|
||||
*/
|
||||
@Binding
|
||||
public Vector2 getVector2(String argument) {
|
||||
String radiusString = argument;
|
||||
String[] radii = radiusString.split(",");
|
||||
final double radiusX;
|
||||
final double radiusZ;
|
||||
switch (radii.length) {
|
||||
case 1:
|
||||
radiusX = radiusZ = PrimitiveBindings.parseNumericInput(radii[0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
radiusX = PrimitiveBindings.parseNumericInput(radii[0]);
|
||||
radiusZ = PrimitiveBindings.parseNumericInput(radii[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InputParseException("You must either specify 1 or 2 radius values.");
|
||||
}
|
||||
return Vector2.at(radiusX, radiusZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a type from a {@link Binding}.
|
||||
*
|
||||
* @param argument the context
|
||||
* @return the requested type
|
||||
* @throws InputParseException on error
|
||||
*/
|
||||
@Binding
|
||||
public BlockVector3 getBlockVector3(String argument) {
|
||||
String radiusString = argument;
|
||||
String[] radii = radiusString.split(",");
|
||||
final double radiusX;
|
||||
final double radiusY;
|
||||
final double radiusZ;
|
||||
switch (radii.length) {
|
||||
case 1:
|
||||
radiusX = radiusY = radiusZ = PrimitiveBindings.parseNumericInput(radii[0]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
radiusX = PrimitiveBindings.parseNumericInput(radii[0]);
|
||||
radiusY = PrimitiveBindings.parseNumericInput(radii[1]);
|
||||
radiusZ = PrimitiveBindings.parseNumericInput(radii[2]);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InputParseException("You must either specify 1 or 3 radius values.");
|
||||
}
|
||||
return BlockVector3.at(radiusX, radiusY, radiusZ);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a type from a {@link Binding}.
|
||||
*
|
||||
* @param argument the context
|
||||
* @return the requested type
|
||||
* @throws InputParseException on error
|
||||
*/
|
||||
@Binding
|
||||
public BlockVector2 getBlockVector2(String argument) {
|
||||
String[] radii = argument.split(",");
|
||||
final double radiusX;
|
||||
final double radiusZ;
|
||||
switch (radii.length) {
|
||||
case 1:
|
||||
radiusX = radiusZ = parseNumericInput(radii[0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
radiusX = parseNumericInput(radii[0]);
|
||||
radiusZ = parseNumericInput(radii[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InputParseException("You must either specify 1 or 2 radius values.");
|
||||
}
|
||||
return BlockVector2.at(radiusX, radiusZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to parse numeric input as either a number or a mathematical expression.
|
||||
*
|
||||
* @param input input
|
||||
* @return a number
|
||||
* @throws InputParseException thrown on parse error
|
||||
*/
|
||||
@Nullable
|
||||
public static Double parseNumericInput(@Nullable String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Double.parseDouble(input);
|
||||
} catch (NumberFormatException e1) {
|
||||
try {
|
||||
Expression expression = Expression.compile(input);
|
||||
return expression.evaluate();
|
||||
} catch (EvaluationException e) {
|
||||
throw new InputParseException(String.format(
|
||||
"Expected '%s' to be a valid number (or a valid mathematical expression)", input));
|
||||
} catch (ExpressionException e) {
|
||||
throw new InputParseException(String.format(
|
||||
"Expected '%s' to be a number or valid math expression (error: %s)", input, e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
package com.fastasyncworldedit.core.extension.platform.binding;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.database.DBHandler;
|
||||
import com.fastasyncworldedit.core.database.RollbackDatabase;
|
||||
import com.fastasyncworldedit.core.regions.FaweMaskManager;
|
||||
import com.fastasyncworldedit.core.util.TextureUtil;
|
||||
import com.fastasyncworldedit.core.util.image.ImageUtil;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.argument.Arguments;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.command.util.annotation.AllowedRegion;
|
||||
import com.sk89q.worldedit.internal.annotation.Selection;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.session.request.Request;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import org.enginehub.piston.inject.InjectedValueAccess;
|
||||
import org.enginehub.piston.inject.InjectedValueStore;
|
||||
import org.enginehub.piston.inject.Key;
|
||||
import org.enginehub.piston.util.ValueProvider;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.net.URI;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ProvideBindings extends Bindings {
|
||||
public ProvideBindings(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
/*
|
||||
Provided
|
||||
*/
|
||||
@Binding
|
||||
public Player getPlayer(Actor actor) {
|
||||
if (actor.isPlayer()) {
|
||||
return (Player) actor;
|
||||
}
|
||||
throw new InputParseException(Caption.of("worldedit.command.player-only"));
|
||||
}
|
||||
|
||||
@Binding
|
||||
public LocalSession getLocalSession(Player player) {
|
||||
return getWorldEdit().getSessionManager().get(player);
|
||||
}
|
||||
|
||||
@Binding
|
||||
public EditSession editSession(LocalSession localSession, Player player, InjectedValueAccess context) {
|
||||
Arguments arguments = context.injectedValue(Key.of(Arguments.class)).orElse(null);
|
||||
String command = arguments == null ? null : arguments.get();
|
||||
EditSession editSession = localSession.createEditSession(player, command);
|
||||
editSession.enableStandardMode();
|
||||
Request.request().setEditSession(editSession);
|
||||
return editSession;
|
||||
}
|
||||
|
||||
@Selection
|
||||
@Binding
|
||||
public Region selection(LocalSession localSession, Player player) {
|
||||
return localSession.getSelection(player.getWorld());
|
||||
}
|
||||
|
||||
@Binding
|
||||
public RollbackDatabase database(World world) {
|
||||
return DBHandler.IMP.getDatabase(world);
|
||||
}
|
||||
|
||||
@AllowedRegion(FaweMaskManager.MaskType.OWNER)
|
||||
@Binding
|
||||
public Region[] regionsOwner(Player player) {
|
||||
return regions(player, FaweMaskManager.MaskType.OWNER);
|
||||
}
|
||||
|
||||
@AllowedRegion(FaweMaskManager.MaskType.MEMBER)
|
||||
@Binding
|
||||
public Region[] regionsMember(Player player) {
|
||||
return regions(player, FaweMaskManager.MaskType.MEMBER);
|
||||
}
|
||||
|
||||
public Region[] regions(Player player, FaweMaskManager.MaskType type) {
|
||||
Region[] regions = player.getCurrentRegions(type);
|
||||
if (regions == null) {
|
||||
throw new IllegalArgumentException(Caption.toString(Caption.of("fawe.error.no.region")));
|
||||
}
|
||||
return regions;
|
||||
}
|
||||
|
||||
@Binding
|
||||
public TextureUtil getTexture(LocalSession session) {
|
||||
return session.getTextureUtil();
|
||||
}
|
||||
|
||||
public static class ImageUri {
|
||||
public final URI uri;
|
||||
private BufferedImage image;
|
||||
|
||||
ImageUri(URI uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public BufferedImage load() {
|
||||
if (image != null) {
|
||||
return image;
|
||||
}
|
||||
return image = ImageUtil.load(uri);
|
||||
}
|
||||
}
|
||||
|
||||
@Binding
|
||||
public Extent getExtent(Actor actor, InjectedValueAccess access) {
|
||||
Optional<EditSession> editSessionOpt = access.injectedValue(Key.of(EditSession.class));
|
||||
if (editSessionOpt.isPresent()) {
|
||||
return editSessionOpt.get();
|
||||
}
|
||||
Extent extent = Request.request().getExtent();
|
||||
if (extent != null) {
|
||||
return extent;
|
||||
}
|
||||
Player plr = getPlayer(actor);
|
||||
EditSession editSession = editSession(getLocalSession(plr), plr, access);
|
||||
if (access instanceof InjectedValueStore) {
|
||||
InjectedValueStore store = (InjectedValueStore) access;
|
||||
store.injectValue(Key.of(EditSession.class), ValueProvider.constant(editSession));
|
||||
}
|
||||
return editSession;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user