diff --git a/config/checkstyle/import-control.xml b/config/checkstyle/import-control.xml
index 28ccad1e4..5bcfffeb3 100644
--- a/config/checkstyle/import-control.xml
+++ b/config/checkstyle/import-control.xml
@@ -16,6 +16,8 @@
+
+
diff --git a/worldedit-bukkit/build.gradle b/worldedit-bukkit/build.gradle
index 335b96c0a..3c5832e9b 100644
--- a/worldedit-bukkit/build.gradle
+++ b/worldedit-bukkit/build.gradle
@@ -8,6 +8,12 @@ repositories {
maven { url 'https://papermc.io/repo/repository/maven-public/' }
}
+configurations.all { Configuration it ->
+ it.resolutionStrategy { ResolutionStrategy rs ->
+ rs.force("com.google.guava:guava:21.0")
+ }
+}
+
dependencies {
compile project(':worldedit-core')
compile 'com.sk89q:dummypermscompat:1.10'
diff --git a/worldedit-core/build.gradle b/worldedit-core/build.gradle
index 3047ad577..5f6cce5a6 100644
--- a/worldedit-core/build.gradle
+++ b/worldedit-core/build.gradle
@@ -7,6 +7,12 @@ apply plugin: 'idea'
apply plugin: 'net.ltgt.apt-eclipse'
apply plugin: 'net.ltgt.apt-idea'
+configurations.all { Configuration it ->
+ it.resolutionStrategy { ResolutionStrategy rs ->
+ rs.force("com.google.guava:guava:21.0")
+ }
+}
+
dependencies {
compile 'de.schlichtherle:truezip:6.8.3'
compile 'rhino:js:1.7R2'
@@ -20,7 +26,8 @@ dependencies {
compile 'com.googlecode.json-simple:json-simple:1.1.1'
compile 'org.slf4j:slf4j-api:1.7.26'
compileOnly 'org.enginehub.piston:core-ap-annotations:0.0.1-SNAPSHOT'
- annotationProcessor 'org.enginehub.piston:core-ap-processor:0.0.1-SNAPSHOT'
+ compile 'org.enginehub.piston:core-ap-runtime:0.0.1-SNAPSHOT'
+ annotationProcessor 'org.enginehub.piston:core-ap-processor:0.0.1-SNAPSHOT'
compile 'org.enginehub.piston:default-impl:0.0.1-SNAPSHOT'
//compile 'net.sf.trove4j:trove4j:3.0.3'
testCompile 'org.mockito:mockito-core:1.9.0-rc1'
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java
index d685318f8..2bdd77bf0 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java
@@ -21,13 +21,11 @@ package com.sk89q.worldedit.command;
import com.google.common.collect.Multimap;
import com.google.common.io.Files;
-import com.sk89q.minecraft.util.commands.CommandContext;
-import com.sk89q.minecraft.util.commands.CommandException;
-import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
@@ -49,6 +47,7 @@ import org.enginehub.piston.annotation.param.ArgFlag;
import org.enginehub.piston.annotation.param.Switch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.enginehub.piston.exception.StopExecutionException;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -138,7 +137,7 @@ public class SchematicCommands {
@Arg(desc = "File name.") String filename,
@Arg(desc = "Format name.", def = "sponge") String formatName,
@Switch(name = 'f', desc = "Overwrite an existing file.") boolean allowOverwrite
- ) throws CommandException, WorldEditException {
+ ) throws WorldEditException {
LocalConfiguration config = worldEdit.getConfiguration();
File dir = worldEdit.getWorkingDirectoryFile(config.saveDir);
@@ -154,7 +153,7 @@ public class SchematicCommands {
boolean overwrite = f.exists();
if (overwrite) {
if (!player.hasPermission("worldedit.schematic.delete")) {
- throw new CommandException("That schematic already exists!");
+ throw new StopExecutionException("That schematic already exists!");
}
if (!allowOverwrite) {
player.printError("That schematic already exists. Use the -f flag to overwrite it.");
@@ -181,7 +180,7 @@ public class SchematicCommands {
File parent = f.getParentFile();
if (parent != null && !parent.exists()) {
if (!parent.mkdirs()) {
- throw new CommandException("Could not create folder for schematics!");
+ throw new StopExecutionException("Could not create folder for schematics!");
}
}
@@ -263,8 +262,13 @@ public class SchematicCommands {
descFooter = "Note: Format is not fully verified until loading."
)
@CommandPermissions("worldedit.schematic.list")
- public void list(Actor actor, CommandContext args,
- @ArgFlag(name = 'p', desc = "Page to view.", def = "1") int page) {
+ public void list(Actor actor,
+ @ArgFlag(name = 'p', desc = "Page to view.", def = "1") int page,
+ @Switch(name = 'd', desc = "Sort by date, oldest first") boolean oldFirst,
+ @Switch(name = 'n', desc = "Sort by date, newest first") boolean newFirst) {
+ if (oldFirst && newFirst) {
+ throw new StopExecutionException("Cannot sort by oldest and newest.");
+ }
File dir = worldEdit.getWorkingDirectoryFile(worldEdit.getConfiguration().saveDir);
List fileList = allFiles(dir);
@@ -286,7 +290,7 @@ public class SchematicCommands {
return;
}
- final int sortType = args.hasFlag('d') ? -1 : args.hasFlag('n') ? 1 : 0;
+ final int sortType = oldFirst ? -1 : newFirst ? 1 : 0;
// cleanup file list
Arrays.sort(files, (f1, f2) -> {
// http://stackoverflow.com/questions/203030/best-way-to-list-files-in-java-sorted-by-date-modified
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/CommandPermissions.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/CommandPermissions.java
new file mode 100644
index 000000000..feefb9aba
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/CommandPermissions.java
@@ -0,0 +1,39 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.command.util;
+
+import org.enginehub.piston.annotation.CommandCondition;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+@CommandCondition(CommandPermissionsConditionGenerator.class)
+public @interface CommandPermissions {
+
+ /**
+ * A list of permissions. Only one permission has to be met
+ * for the command to be permitted.
+ *
+ * @return a list of permissions strings
+ */
+ String[] value();
+
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/CommandPermissionsConditionGenerator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/CommandPermissionsConditionGenerator.java
new file mode 100644
index 000000000..d00d286d6
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/CommandPermissionsConditionGenerator.java
@@ -0,0 +1,49 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.command.util;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Key;
+import com.sk89q.worldedit.extension.platform.Actor;
+import org.enginehub.piston.Command;
+import org.enginehub.piston.gen.CommandConditionGenerator;
+import org.enginehub.piston.util.NonnullByDefault;
+
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+@NonnullByDefault
+public class CommandPermissionsConditionGenerator implements CommandConditionGenerator {
+
+ private static final Key ACTOR_KEY = Key.get(Actor.class);
+
+ @Override
+ public Command.Condition generateCondition(Method commandMethod) {
+ CommandPermissions annotation = commandMethod.getAnnotation(CommandPermissions.class);
+ checkNotNull(annotation, "Annotation is missing from commandMethod");
+ Set permissions = ImmutableSet.copyOf(annotation.value());
+ return p -> {
+ Actor actor = p.injectedValue(ACTOR_KEY);
+ return permissions.stream().anyMatch(actor::hasPermission);
+ };
+ }
+}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java
index a0be07b65..9a2a9da78 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java
@@ -19,10 +19,8 @@
package com.sk89q.worldedit.extension.platform;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.sk89q.worldedit.util.command.composition.LegacyCommandAdapter.adapt;
-
import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
@@ -41,6 +39,7 @@ import com.sk89q.worldedit.command.HistoryCommands;
import com.sk89q.worldedit.command.NavigationCommands;
import com.sk89q.worldedit.command.RegionCommands;
import com.sk89q.worldedit.command.SchematicCommands;
+import com.sk89q.worldedit.command.SchematicCommandsRegistration;
import com.sk89q.worldedit.command.ScriptingCommands;
import com.sk89q.worldedit.command.SelectionCommands;
import com.sk89q.worldedit.command.SnapshotCommands;
@@ -57,6 +56,7 @@ import com.sk89q.worldedit.command.composition.DeformCommand;
import com.sk89q.worldedit.command.composition.PaintCommand;
import com.sk89q.worldedit.command.composition.SelectionCommand;
import com.sk89q.worldedit.command.composition.ShapedBrushCommand;
+import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
@@ -69,8 +69,10 @@ import com.sk89q.worldedit.internal.command.UserCommandCompleter;
import com.sk89q.worldedit.internal.command.WorldEditBinding;
import com.sk89q.worldedit.internal.command.WorldEditExceptionConverter;
import com.sk89q.worldedit.session.request.Request;
+import com.sk89q.worldedit.util.command.CommandCallable;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.InvalidUsageException;
+import com.sk89q.worldedit.util.command.SimpleDescription;
import com.sk89q.worldedit.util.command.composition.ProvidedValue;
import com.sk89q.worldedit.util.command.fluent.CommandGraph;
import com.sk89q.worldedit.util.command.parametric.ExceptionConverter;
@@ -82,6 +84,7 @@ import com.sk89q.worldedit.util.formatting.component.CommandUsageBox;
import com.sk89q.worldedit.util.logging.DynamicStreamHandler;
import com.sk89q.worldedit.util.logging.LogFormat;
import com.sk89q.worldedit.world.World;
+import org.enginehub.piston.DefaultCommandManagerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -91,6 +94,9 @@ import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.regex.Pattern;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.sk89q.worldedit.util.command.composition.LegacyCommandAdapter.adapt;
+
/**
* Handles the registration and invocation of commands.
*
@@ -158,10 +164,7 @@ public final class CommandManager {
.describeAs("WorldEdit commands")
.registerMethods(new WorldEditCommands(worldEdit))
.parent()
- .group("schematic", "schem", "/schematic", "/schem")
- .describeAs("Schematic commands for saving/loading areas")
- .registerMethods(new SchematicCommands(worldEdit))
- .parent()
+ .register(schematicCommands(),"schematic", "schem", "/schematic", "/schem")
.group("snapshot", "snap")
.describeAs("Schematic commands for saving/loading areas")
.registerMethods(new SnapshotCommands(worldEdit))
@@ -189,6 +192,21 @@ public final class CommandManager {
.getDispatcher();
}
+ private CommandCallable schematicCommands() {
+ SimpleDescription desc = new SimpleDescription();
+ desc.setDescription("Schematic commands for saving/loading areas");
+ desc.setPermissions(ImmutableList.of());
+ org.enginehub.piston.CommandManager manager = DefaultCommandManagerService.getInstance()
+ .newCommandManager();
+ new SchematicCommandsRegistration(
+ manager,
+ new SchematicCommands(worldEdit),
+ new CommandPermissionsConditionGenerator()
+ );
+
+ return new CommandManagerCallable(worldEdit, manager, desc);
+ }
+
public ExceptionConverter getExceptionConverter() {
return exceptionConverter;
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManagerCallable.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManagerCallable.java
new file mode 100644
index 000000000..bb6079713
--- /dev/null
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManagerCallable.java
@@ -0,0 +1,90 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.extension.platform;
+
+import com.google.common.base.Splitter;
+import com.google.inject.Key;
+import com.sk89q.minecraft.util.commands.CommandException;
+import com.sk89q.minecraft.util.commands.CommandLocals;
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.LocalSession;
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.entity.Player;
+import com.sk89q.worldedit.util.command.CommandCallable;
+import com.sk89q.worldedit.util.command.Description;
+import org.enginehub.piston.CommandManager;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Hack to get {@link CommandManager} working under {@link CommandCallable}.
+ */
+public class CommandManagerCallable implements CommandCallable {
+
+ private final WorldEdit worldEdit;
+ private final CommandManager manager;
+ private final Description description;
+
+ public CommandManagerCallable(WorldEdit worldEdit, CommandManager manager, Description description) {
+ this.worldEdit = worldEdit;
+ this.manager = manager;
+ this.description = description;
+ }
+
+ @Override
+ public Object call(String arguments, CommandLocals locals, String[] parentCommands) throws CommandException {
+ manager.injectValue(Key.get(Actor.class), () -> locals.get(Actor.class));
+ manager.injectValue(Key.get(Player.class), () -> getPlayer(locals));
+ manager.injectValue(Key.get(LocalSession.class), () -> {
+ Player sender = getPlayer(locals);
+ return worldEdit.getSessionManager().get(sender);
+ });
+ manager.injectValue(Key.get(EditSession.class), () -> {
+ Player sender = getPlayer(locals);
+ LocalSession session = worldEdit.getSessionManager().get(sender);
+ EditSession editSession = session.createEditSession(sender);
+ editSession.enableStandardMode();
+ session.tellVersion(sender);
+ return editSession;
+ });
+ return manager.execute(Splitter.on(' ').splitToList(arguments));
+ }
+
+ private Player getPlayer(CommandLocals locals) {
+ Actor actor = locals.get(Actor.class);
+ return actor instanceof Player ? (Player) actor : null;
+ }
+
+ @Override
+ public Description getDescription() {
+ return description;
+ }
+
+ @Override
+ public boolean testPermission(CommandLocals locals) {
+ return true;
+ }
+
+ @Override
+ public List getSuggestions(String arguments, CommandLocals locals) throws CommandException {
+ return Collections.emptyList();
+ }
+}
diff --git a/worldedit-forge/build.gradle b/worldedit-forge/build.gradle
index 8fe3fb9af..62b38c8e8 100644
--- a/worldedit-forge/build.gradle
+++ b/worldedit-forge/build.gradle
@@ -16,6 +16,12 @@ apply plugin: 'net.minecraftforge.gradle'
def minecraftVersion = "1.13.2"
def forgeVersion = "25.0.76"
+configurations.all { Configuration it ->
+ it.resolutionStrategy { ResolutionStrategy rs ->
+ rs.force("com.google.guava:guava:21.0")
+ }
+}
+
dependencies {
compile project(':worldedit-core')
compile 'org.apache.logging.log4j:log4j-slf4j-impl:2.11.2'