From e021358b5cf4f77c66840abd9db2828daf7fe015 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Fri, 10 Mar 2017 07:32:35 +1100 Subject: [PATCH] Fix gen cmd not parsing expressions, + other fixes Fix console EditSession using wrong fastmode setting Fix minor lighting error --- build.gradle | 2 +- .../fawe/command/FawePrimitiveBinding.java | 306 ++++++++++++++++++ .../com/boydti/fawe/command/LongBinding.java | 46 --- .../com/boydti/fawe/example/NMSRelighter.java | 2 +- .../java/com/sk89q/worldedit/EditSession.java | 2 +- .../worldedit/command/GenerationCommands.java | 41 +-- .../command/parametric/ParametricBuilder.java | 5 +- 7 files changed, 334 insertions(+), 70 deletions(-) create mode 100644 core/src/main/java/com/boydti/fawe/command/FawePrimitiveBinding.java delete mode 100644 core/src/main/java/com/boydti/fawe/command/LongBinding.java diff --git a/build.gradle b/build.gradle index f5678195..6e950f4f 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ ext { date = git.head().date.format("yy.MM.dd") revision = "-${git.head().abbreviatedId}" parents = git.head().parentIds; - index = -86; // Offset to mach CI + index = -87; // Offset to mach CI int major, minor, patch; major = minor = patch = 0; for (;parents != null && !parents.isEmpty();index++) { diff --git a/core/src/main/java/com/boydti/fawe/command/FawePrimitiveBinding.java b/core/src/main/java/com/boydti/fawe/command/FawePrimitiveBinding.java new file mode 100644 index 00000000..a3c89bce --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/command/FawePrimitiveBinding.java @@ -0,0 +1,306 @@ +package com.boydti.fawe.command; + +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.ExpressionException; +import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; +import com.sk89q.worldedit.util.command.binding.Range; +import com.sk89q.worldedit.util.command.binding.Text; +import com.sk89q.worldedit.util.command.binding.Validate; +import com.sk89q.worldedit.util.command.parametric.ArgumentStack; +import com.sk89q.worldedit.util.command.parametric.BindingBehavior; +import com.sk89q.worldedit.util.command.parametric.BindingHelper; +import com.sk89q.worldedit.util.command.parametric.BindingMatch; +import com.sk89q.worldedit.util.command.parametric.ParameterException; +import java.lang.annotation.Annotation; +import javax.annotation.Nullable; + +public class FawePrimitiveBinding extends BindingHelper { + @BindingMatch(type = { Long.class, long.class }, + behavior = BindingBehavior.CONSUMES, + consumedCount = 1, + provideModifiers = true) + public Long getLong(ArgumentStack context, Annotation[] modifiers) throws ParameterException { + try { + Long v = Long.parseLong(context.next()); + validate(v, modifiers); + return v; + + } catch (NumberFormatException ignore) { + return null; + } + } + + private static void validate(long number, Annotation[] modifiers) + throws ParameterException { + for (Annotation modifier : modifiers) { + if (modifier instanceof Range) { + Range range = (Range) modifier; + if (number < range.min()) { + throw new ParameterException( + String.format( + "A valid value is greater than or equal to %s " + + "(you entered %s)", range.min(), number)); + } else if (number > range.max()) { + throw new ParameterException( + String.format( + "A valid value is less than or equal to %s " + + "(you entered %s)", range.max(), number)); + } + } + } + } + + /** + * Gets a type from a {@link ArgumentStack}. + * + * @param context the context + * @param text the text annotation + * @param modifiers a list of modifiers + * @return the requested type + * @throws ParameterException on error + */ + @BindingMatch(classifier = Text.class, + type = String.class, + behavior = BindingBehavior.CONSUMES, + consumedCount = -1, + provideModifiers = true) + public String getText(ArgumentStack context, Text text, Annotation[] modifiers) + throws ParameterException { + String v = context.remaining(); + validate(v, modifiers); + return v; + } + + /** + * Gets a type from a {@link ArgumentStack}. + * + * @param context the context + * @param modifiers a list of modifiers + * @return the requested type + * @throws ParameterException on error + */ + @BindingMatch(type = String.class, + behavior = BindingBehavior.CONSUMES, + consumedCount = 1, + provideModifiers = true) + public String getString(ArgumentStack context, Annotation[] modifiers) + throws ParameterException { + String v = context.next(); + validate(v, modifiers); + return v; + } + + /** + * Gets a type from a {@link ArgumentStack}. + * + * @param context the context + * @return the requested type + * @throws ParameterException on error + */ + @BindingMatch(type = { Boolean.class, boolean.class }, + behavior = BindingBehavior.CONSUMES, + consumedCount = 1) + public Boolean getBoolean(ArgumentStack context) throws ParameterException { + return context.nextBoolean(); + } + + /** + * Try to parse numeric input as either a number or a mathematical expression. + * + * @param input input + * @return a number + * @throws ParameterException thrown on parse error + */ + public static @Nullable + Double parseNumericInput(@Nullable String input) throws ParameterException { + if (input == null) { + return null; + } + System.out.println("PARSE " + input); + + try { + return Double.parseDouble(input); + } catch (NumberFormatException e1) { + System.out.println("NUMBER FORMAT EXCEPTION " + e1); + try { + Expression expression = Expression.compile(input); + return expression.evaluate(); + } catch (EvaluationException e) { + throw new ParameterException(String.format( + "Expected '%s' to be a valid number (or a valid mathematical expression)", input)); + } catch (ExpressionException e) { + throw new ParameterException(String.format( + "Expected '%s' to be a number or valid math expression (error: %s)", input, e.getMessage())); + } + } + } + + /** + * Gets a type from a {@link ArgumentStack}. + * + * @param context the context + * @param modifiers a list of modifiers + * @return the requested type + * @throws ParameterException on error + */ + @BindingMatch(type = { Integer.class, int.class }, + behavior = BindingBehavior.CONSUMES, + consumedCount = 1, + provideModifiers = true) + public Integer getInteger(ArgumentStack context, Annotation[] modifiers) throws ParameterException { + Double v = parseNumericInput(context.next()); + if (v != null) { + int intValue = v.intValue(); + validate(intValue, modifiers); + return intValue; + } else { + return null; + } + } + + /** + * Gets a type from a {@link ArgumentStack}. + * + * @param context the context + * @param modifiers a list of modifiers + * @return the requested type + * @throws ParameterException on error + */ + @BindingMatch(type = { Short.class, short.class }, + behavior = BindingBehavior.CONSUMES, + consumedCount = 1, + provideModifiers = true) + public Short getShort(ArgumentStack context, Annotation[] modifiers) throws ParameterException { + Integer v = getInteger(context, modifiers); + if (v != null) { + return v.shortValue(); + } + return null; + } + + /** + * Gets a type from a {@link ArgumentStack}. + * + * @param context the context + * @param modifiers a list of modifiers + * @return the requested type + * @throws ParameterException on error + */ + @BindingMatch(type = { Double.class, double.class }, + behavior = BindingBehavior.CONSUMES, + consumedCount = 1, + provideModifiers = true) + public Double getDouble(ArgumentStack context, Annotation[] modifiers) throws ParameterException { + Double v = parseNumericInput(context.next()); + if (v != null) { + validate(v, modifiers); + return v; + } else { + return null; + } + } + + /** + * Gets a type from a {@link ArgumentStack}. + * + * @param context the context + * @param modifiers a list of modifiers + * @return the requested type + * @throws ParameterException on error + */ + @BindingMatch(type = { Float.class, float.class }, + behavior = BindingBehavior.CONSUMES, + consumedCount = 1, + provideModifiers = true) + public Float getFloat(ArgumentStack context, Annotation[] modifiers) throws ParameterException { + Double v = getDouble(context, modifiers); + if (v != null) { + return v.floatValue(); + } + return null; + } + + /** + * Validate a number value using relevant modifiers. + * + * @param number the number + * @param modifiers the list of modifiers to scan + * @throws ParameterException on a validation error + */ + private static void validate(double number, Annotation[] modifiers) + throws ParameterException { + for (Annotation modifier : modifiers) { + if (modifier instanceof Range) { + Range range = (Range) modifier; + if (number < range.min()) { + throw new ParameterException( + String.format( + "A valid value is greater than or equal to %s " + + "(you entered %s)", range.min(), number)); + } else if (number > range.max()) { + throw new ParameterException( + String.format( + "A valid value is less than or equal to %s " + + "(you entered %s)", range.max(), number)); + } + } + } + } + + /** + * Validate a number value using relevant modifiers. + * + * @param number the number + * @param modifiers the list of modifiers to scan + * @throws ParameterException on a validation error + */ + private static void validate(int number, Annotation[] modifiers) + throws ParameterException { + for (Annotation modifier : modifiers) { + if (modifier instanceof Range) { + Range range = (Range) modifier; + if (number < range.min()) { + throw new ParameterException( + String.format( + "A valid value is greater than or equal to %s " + + "(you entered %s)", range.min(), number)); + } else if (number > range.max()) { + throw new ParameterException( + String.format( + "A valid value is less than or equal to %s " + + "(you entered %s)", range.max(), number)); + } + } + } + } + + /** + * Validate a string value using relevant modifiers. + * + * @param string the string + * @param modifiers the list of modifiers to scan + * @throws ParameterException on a validation error + */ + private static void validate(String string, Annotation[] modifiers) + throws ParameterException { + if (string == null) { + return; + } + + for (Annotation modifier : modifiers) { + if (modifier instanceof Validate) { + Validate validate = (Validate) modifier; + + if (!validate.regex().isEmpty()) { + if (!string.matches(validate.regex())) { + throw new ParameterException( + String.format( + "The given text doesn't match the right " + + "format (technically speaking, the 'format' is %s)", + validate.regex())); + } + } + } + } + } +} diff --git a/core/src/main/java/com/boydti/fawe/command/LongBinding.java b/core/src/main/java/com/boydti/fawe/command/LongBinding.java deleted file mode 100644 index dd57c8ac..00000000 --- a/core/src/main/java/com/boydti/fawe/command/LongBinding.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.boydti.fawe.command; - -import com.sk89q.worldedit.util.command.binding.Range; -import com.sk89q.worldedit.util.command.parametric.ArgumentStack; -import com.sk89q.worldedit.util.command.parametric.BindingBehavior; -import com.sk89q.worldedit.util.command.parametric.BindingHelper; -import com.sk89q.worldedit.util.command.parametric.BindingMatch; -import com.sk89q.worldedit.util.command.parametric.ParameterException; -import java.lang.annotation.Annotation; - -public class LongBinding extends BindingHelper { - @BindingMatch(type = { Long.class, long.class }, - behavior = BindingBehavior.CONSUMES, - consumedCount = 1, - provideModifiers = true) - public Long getInteger(ArgumentStack context, Annotation[] modifiers) throws ParameterException { - try { - Long v = Long.parseLong(context.next()); - validate(v, modifiers); - return v; - - } catch (NumberFormatException ignore) { - return null; - } - } - - private static void validate(long number, Annotation[] modifiers) - throws ParameterException { - for (Annotation modifier : modifiers) { - if (modifier instanceof Range) { - Range range = (Range) modifier; - if (number < range.min()) { - throw new ParameterException( - String.format( - "A valid value is greater than or equal to %s " + - "(you entered %s)", range.min(), number)); - } else if (number > range.max()) { - throw new ParameterException( - String.format( - "A valid value is less than or equal to %s " + - "(you entered %s)", range.max(), number)); - } - } - } - } -} diff --git a/core/src/main/java/com/boydti/fawe/example/NMSRelighter.java b/core/src/main/java/com/boydti/fawe/example/NMSRelighter.java index 336afd78..31d355c6 100644 --- a/core/src/main/java/com/boydti/fawe/example/NMSRelighter.java +++ b/core/src/main/java/com/boydti/fawe/example/NMSRelighter.java @@ -194,7 +194,7 @@ public class NMSRelighter implements Relighter{ } } - public void addLightUpdate(int x, int y, int z) { + public synchronized void addLightUpdate(int x, int y, int z) { long index = MathMan.pairInt((int) x >> 4, (int) z >> 4); Map currentMap = lightQueue.get(index); if (currentMap == null) { diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index 206df035..3c6907e4 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -236,7 +236,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting } if (fastmode == null) { if (player == null) { - fastmode = Settings.IMP.HISTORY.ENABLE_FOR_CONSOLE; + fastmode = !Settings.IMP.HISTORY.ENABLE_FOR_CONSOLE; } else { fastmode = player.getSession().hasFastMode(); } diff --git a/core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java b/core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java index c0bb89a5..fbb5fd21 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.command; +import com.boydti.fawe.command.FawePrimitiveBinding; import com.boydti.fawe.config.BBC; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandPermissions; @@ -40,10 +41,14 @@ import com.sk89q.worldedit.util.command.binding.Range; import com.sk89q.worldedit.util.command.binding.Switch; import com.sk89q.worldedit.util.command.binding.Text; import com.sk89q.worldedit.util.command.parametric.Optional; +import com.sk89q.worldedit.util.command.parametric.ParameterException; import com.sk89q.worldedit.world.biome.BaseBiome; + import static com.google.common.base.Preconditions.checkNotNull; -import static com.sk89q.minecraft.util.commands.Logging.LogMode.*; +import static com.sk89q.minecraft.util.commands.Logging.LogMode.ALL; +import static com.sk89q.minecraft.util.commands.Logging.LogMode.PLACEMENT; +import static com.sk89q.minecraft.util.commands.Logging.LogMode.POSITION; /** * Commands for the generation of shapes and other objects. @@ -76,7 +81,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.cylinder") @Logging(PLACEMENT) - public void hcyl(Player player, LocalSession session, EditSession editSession, Pattern pattern, String radiusString, @Optional("1") int height) throws WorldEditException { + public void hcyl(Player player, LocalSession session, EditSession editSession, Pattern pattern, String radiusString, @Optional("1") int height) throws WorldEditException, ParameterException { cyl(player, session, editSession, pattern, radiusString, height, true); } @@ -95,17 +100,17 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.cylinder") @Logging(PLACEMENT) - public void cyl(Player player, LocalSession session, EditSession editSession, Pattern pattern, String radiusString, @Optional("1") int height, @Switch('h') boolean hollow) throws WorldEditException { + public void cyl(Player player, LocalSession session, EditSession editSession, Pattern pattern, String radiusString, @Optional("1") int height, @Switch('h') boolean hollow) throws WorldEditException, ParameterException { String[] radii = radiusString.split(","); final double radiusX, radiusZ; switch (radii.length) { case 1: - radiusX = radiusZ = Math.max(1, Double.parseDouble(radii[0])); + radiusX = radiusZ = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[0])); break; case 2: - radiusX = Math.max(1, Double.parseDouble(radii[0])); - radiusZ = Math.max(1, Double.parseDouble(radii[1])); + radiusX = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[0])); + radiusZ = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[1])); break; default: @@ -136,7 +141,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.sphere") @Logging(PLACEMENT) - public void hsphere(Player player, LocalSession session, EditSession editSession, Pattern pattern, String radiusString, @Optional("false") boolean raised) throws WorldEditException { + public void hsphere(Player player, LocalSession session, EditSession editSession, Pattern pattern, String radiusString, @Optional("false") boolean raised) throws WorldEditException, ParameterException { sphere(player, session, editSession, pattern, radiusString, raised, true); } @@ -155,18 +160,18 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.sphere") @Logging(PLACEMENT) - public void sphere(Player player, LocalSession session, EditSession editSession, Pattern pattern, String radiusString, @Optional("false") boolean raised, @Switch('h') boolean hollow) throws WorldEditException { + public void sphere(Player player, LocalSession session, EditSession editSession, Pattern pattern, String radiusString, @Optional("false") boolean raised, @Switch('h') boolean hollow) throws WorldEditException, ParameterException { String[] radii = radiusString.split(","); final double radiusX, radiusY, radiusZ; switch (radii.length) { case 1: - radiusX = radiusY = radiusZ = Math.max(1, Double.parseDouble(radii[0])); + radiusX = radiusY = radiusZ = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[0])); break; case 3: - radiusX = Math.max(1, Double.parseDouble(radii[0])); - radiusY = Math.max(1, Double.parseDouble(radii[1])); - radiusZ = Math.max(1, Double.parseDouble(radii[2])); + radiusX = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[0])); + radiusY = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[1])); + radiusZ = Math.max(1, FawePrimitiveBinding.parseNumericInput(radii[2])); break; default: @@ -198,7 +203,7 @@ public class GenerationCommands { @CommandPermissions("worldedit.generation.forest") @Logging(POSITION) @SuppressWarnings("deprecation") - public void forestGen(Player player, LocalSession session, EditSession editSession, @Optional("10") int size, @Optional("tree") TreeType type, @Optional("5") double density) throws WorldEditException { + public void forestGen(Player player, LocalSession session, EditSession editSession, @Optional("10") int size, @Optional("tree") TreeType type, @Optional("5") double density) throws WorldEditException, ParameterException { density = density / 100; int affected = editSession.makeForest(session.getPlacementPosition(player), size, density, new TreeGenerator(type)); BBC.COMMAND_TREE.send(player, affected); @@ -213,7 +218,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.pumpkins") @Logging(POSITION) - public void pumpkins(Player player, LocalSession session, EditSession editSession, @Optional("10") int apothem) throws WorldEditException { + public void pumpkins(Player player, LocalSession session, EditSession editSession, @Optional("10") int apothem) throws WorldEditException, ParameterException { int affected = editSession.makePumpkinPatches(session.getPlacementPosition(player), apothem); BBC.COMMAND_PUMPKIN.send(player, affected); } @@ -227,7 +232,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.pyramid") @Logging(PLACEMENT) - public void hollowPyramid(Player player, LocalSession session, EditSession editSession, Pattern pattern, @Range(min = 1) int size) throws WorldEditException { + public void hollowPyramid(Player player, LocalSession session, EditSession editSession, Pattern pattern, @Range(min = 1) int size) throws WorldEditException, ParameterException { pyramid(player, session, editSession, pattern, size, true); } @@ -241,7 +246,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.pyramid") @Logging(PLACEMENT) - public void pyramid(Player player, LocalSession session, EditSession editSession, Pattern pattern, @Range(min = 1) int size, @Switch('h') boolean hollow) throws WorldEditException { + public void pyramid(Player player, LocalSession session, EditSession editSession, Pattern pattern, @Range(min = 1) int size, @Switch('h') boolean hollow) throws WorldEditException, ParameterException { Vector pos = session.getPlacementPosition(player); worldEdit.checkMaxRadius(size); int affected = editSession.makePyramid(pos, Patterns.wrap(pattern), size, !hollow); @@ -277,7 +282,7 @@ public class GenerationCommands { @Switch('h') boolean hollow, @Switch('r') boolean useRawCoords, @Switch('o') boolean offset, - @Switch('c') boolean offsetCenter) throws WorldEditException { + @Switch('c') boolean offsetCenter) throws WorldEditException, ParameterException { final Vector zero; Vector unit; @@ -343,7 +348,7 @@ public class GenerationCommands { @Switch('h') boolean hollow, @Switch('r') boolean useRawCoords, @Switch('o') boolean offset, - @Switch('c') boolean offsetCenter) throws WorldEditException { + @Switch('c') boolean offsetCenter) throws WorldEditException, ParameterException { final Vector zero; Vector unit; diff --git a/core/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricBuilder.java b/core/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricBuilder.java index e8ba1ad0..f7673807 100644 --- a/core/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricBuilder.java +++ b/core/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricBuilder.java @@ -19,7 +19,7 @@ package com.sk89q.worldedit.util.command.parametric; -import com.boydti.fawe.command.LongBinding; +import com.boydti.fawe.command.FawePrimitiveBinding; import com.boydti.fawe.config.Commands; import com.google.common.collect.ImmutableBiMap.Builder; import com.sk89q.minecraft.util.commands.Command; @@ -71,8 +71,7 @@ public class ParametricBuilder { * {@link StandardBindings} and default bindings.

*/ public ParametricBuilder() { - addBinding(new PrimitiveBindings()); - addBinding(new LongBinding()); + addBinding(new FawePrimitiveBinding()); addBinding(new StandardBindings()); }