Skip to content
Permalink
Browse files

feature(cli): Added a CLI version of WorldEdit, and allowed most comm…

…ands to be run from console (#508)

* Re-do commits to avoid awful rebase

* You can load and save a schematic file now. Still gotta setup ability to use commands as a console actor.

* Add a world override concept to LocalSession, and allow a lot more commands to be performed by actors.

* Fixed commands, and set the loaded schematic as the world override in CLI

* Properly load tags

* Added 1.14.4 data values

* Allow a majority of commands to be performed by the console.

* Fixed a lot of PR requested changes

* Added a Locatable interface and use that for getting the location of the player in commands.

* Added script support. Currently requires a newline at the end of the script.

* Shade everything to allow this to run locally - should probably minimize this to an extent later.

* Actually hook up the version

* Added a //world command to set the override

* Fixed a missed checkstyle issue

* Added CommandBlock support to Bukkit

* Make command block support configurable

* Minor cleanup and implementing a few of the final functions

* Fixed most issues from PR

* Improve UX, saving is now automatic and unknown command messages show

* Better save docs and support any clipboard format

* Include the entire formats list

* Arrays.copyOf

* Clear the world override if the selector is called on another world.

* Update logging extent to allow basic logging with non-player actors
  • Loading branch information...
me4502 committed Aug 25, 2019
1 parent a0b9810 commit 0620478763bfd5355a6350ed06f9c6ee1741de8b
Showing with 2,383 additions and 566 deletions.
  1. +5 −0 config/checkstyle/import-control.xml
  2. +1 −1 settings.gradle.kts
  3. +0 −6 worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockCategoryRegistry.java
  4. +160 −0 worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBlockCommandSender.java
  5. +5 −31 worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java
  6. +2 −0 worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitConfiguration.java
  7. +0 −6 worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitItemCategoryRegistry.java
  8. +6 −0 worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java
  9. +3 −0 worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java
  10. +1 −0 worldedit-bukkit/src/main/resources/defaults/config.yml
  11. +33 −0 worldedit-cli/build.gradle.kts
  12. +37 −0 worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockCategoryRegistry.java
  13. +73 −0 worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockRegistry.java
  14. +164 −0 worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLICommandSender.java
  15. +40 −0 worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIConfiguration.java
  16. +36 −0 worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIItemCategoryRegistry.java
  17. +159 −0 worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java
  18. +64 −0 worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIRegistries.java
  19. +44 −0 worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIWorld.java
  20. +335 −0 worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIWorldEdit.java
  21. +77 −0 worldedit-cli/src/main/java/com/sk89q/worldedit/cli/data/FileRegistries.java
  22. +217 −0 worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java
  23. +1 −0 worldedit-cli/src/main/resources/com/sk89q/worldedit/cli/data/1631.json
  24. +1 −0 worldedit-cli/src/main/resources/com/sk89q/worldedit/cli/data/1963.json
  25. +1 −0 worldedit-cli/src/main/resources/com/sk89q/worldedit/cli/data/1968.json
  26. +1 −0 worldedit-cli/src/main/resources/com/sk89q/worldedit/cli/data/1976.json
  27. +33 −0 worldedit-cli/src/main/resources/defaults/worldedit.properties
  28. +21 −0 worldedit-cli/src/main/resources/log4j2.xml
  29. +10 −10 worldedit-core/src/main/java/com/sk89q/worldedit/EditSessionFactory.java
  30. +62 −24 worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java
  31. +27 −0 worldedit-core/src/main/java/com/sk89q/worldedit/MissingWorldException.java
  32. +11 −11 worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java
  33. +13 −11 worldedit-core/src/main/java/com/sk89q/worldedit/command/ChunkCommands.java
  34. +22 −21 worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java
  35. +7 −5 worldedit-core/src/main/java/com/sk89q/worldedit/command/ExpandCommands.java
  36. +34 −18 worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java
  37. +41 −35 worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java
  38. +3 −2 worldedit-core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java
  39. +52 −47 worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java
  40. +21 −21 worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java
  41. +62 −56 worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java
  42. +36 −34 worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotCommands.java
  43. +16 −15 worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java
  44. +56 −76 worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java
  45. +11 −6 worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java
  46. +81 −0 worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/WorldConverter.java
  47. +2 −1 worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SelectionWand.java
  48. +2 −24 worldedit-core/src/main/java/com/sk89q/worldedit/entity/Entity.java
  49. +5 −8 worldedit-core/src/main/java/com/sk89q/worldedit/entity/Player.java
  50. +51 −0 worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractNonPlayerActor.java
  51. +5 −12 worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java
  52. +69 −0 worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Locatable.java
  53. +48 −25 worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java
  54. +1 −1 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java
  55. +9 −0 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardReader.java
  56. +35 −10 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java
  57. +13 −11 worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/CommandLoggingHandler.java
  58. +6 −0 ...ore/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java
  59. +20 −0 worldedit-core/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java
  60. +5 −0 worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java
  61. +2 −1 worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java
  62. +3 −1 worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/CategoryRegistry.java
  63. +0 −6 worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullBlockCategoryRegistry.java
  64. +0 −6 worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullItemCategoryRegistry.java
  65. +0 −6 worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricBlockCategoryRegistry.java
  66. +0 −6 worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricItemCategoryRegistry.java
  67. +8 −0 worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java
  68. +0 −6 worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockCategoryRegistry.java
  69. +0 −6 worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeItemCategoryRegistry.java
  70. +6 −0 worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java
  71. +1 −0 worldedit-libs/cli/build.gradle.kts
  72. +7 −0 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java
@@ -48,6 +48,11 @@
<allow pkg="io.papermc.lib"/>
</subpackage>

<subpackage name="cli">
<allow pkg="org.apache.logging.log4j"/>
<allow pkg="org.apache.commons.cli" />
</subpackage>

<subpackage name="forge">
<allow pkg="cpw"/>
<allow pkg="net.minecraft"/>
@@ -2,7 +2,7 @@ rootProject.name = "worldedit"

include("worldedit-libs")

listOf("bukkit", "core", "forge", "sponge", "fabric").forEach {
listOf("bukkit", "core", "forge", "sponge", "fabric", "cli").forEach {
include("worldedit-libs:$it")
include("worldedit-$it")
}
@@ -19,7 +19,6 @@

package com.sk89q.worldedit.bukkit;

import com.sk89q.worldedit.registry.Category;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BlockCategoryRegistry;
import org.bukkit.Bukkit;
@@ -44,9 +43,4 @@
Tag<Material> tag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, new NamespacedKey(namespace, key), Material.class);
return getFromBukkitTag(tag);
}

@Override
public Set<BlockType> getAll(Category<BlockType> category) {
return getCategorisedByName(category.getId());
}
}
@@ -0,0 +1,160 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.worldedit.bukkit;

import static com.google.common.base.Preconditions.checkNotNull;

import com.sk89q.worldedit.extension.platform.AbstractNonPlayerActor;
import com.sk89q.worldedit.extension.platform.Locatable;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.session.SessionKey;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.adapter.bukkit.TextAdapter;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import org.bukkit.Material;
import org.bukkit.command.BlockCommandSender;

import java.util.UUID;

import javax.annotation.Nullable;

public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements Locatable {

private final BlockCommandSender sender;
private final WorldEditPlugin plugin;
private final Location location;
private final UUID uuid;

public BukkitBlockCommandSender(WorldEditPlugin plugin, BlockCommandSender sender) {
checkNotNull(plugin);
checkNotNull(sender);

this.plugin = plugin;
this.sender = sender;
this.location = BukkitAdapter.adapt(sender.getBlock().getLocation());
this.uuid = new UUID(location.toVector().toBlockPoint().hashCode(), location.getExtent().hashCode());
}

@Override
public String getName() {
return sender.getName();
}

@Override
public void printRaw(String msg) {
for (String part : msg.split("\n")) {
sender.sendMessage(part);
}
}

@Override
public void print(String msg) {
for (String part : msg.split("\n")) {
print(TextComponent.of(part, TextColor.LIGHT_PURPLE));
}
}

@Override
public void printDebug(String msg) {
for (String part : msg.split("\n")) {
print(TextComponent.of(part, TextColor.GRAY));
}
}

@Override
public void printError(String msg) {
for (String part : msg.split("\n")) {
print(TextComponent.of(part, TextColor.RED));
}
}

@Override
public void print(Component component) {
TextAdapter.sendComponent(sender, component);
}

@Override
public Location getLocation() {
return this.location;
}

@Override
public boolean setLocation(Location location) {
return false;
}

@Override
public Extent getExtent() {
return this.location.getExtent();
}

@Override
public UUID getUniqueId() {
return uuid;
}

@Override
public String[] getGroups() {
return new String[0];
}

@Override
public void checkPermission(String permission) throws AuthorizationException {
if (!hasPermission(permission)) {
throw new AuthorizationException();
}
}

@Override
public boolean hasPermission(String permission) {
return sender.hasPermission(permission);
}

@Override
public SessionKey getSessionKey() {
return new SessionKey() {
@Nullable
@Override
public String getName() {
return sender.getName();
}

@Override
public boolean isActive() {
return sender.getBlock().getType() == Material.COMMAND_BLOCK
|| sender.getBlock().getType() == Material.CHAIN_COMMAND_BLOCK
|| sender.getBlock().getType() == Material.REPEATING_COMMAND_BLOCK;
}

@Override
public boolean isPersistent() {
return false;
}

@Override
public UUID getUniqueId() {
return uuid;
}
};
}
}
@@ -22,21 +22,19 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.extension.platform.AbstractNonPlayerActor;
import com.sk89q.worldedit.session.SessionKey;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.adapter.bukkit.TextAdapter;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import java.io.File;
import java.util.UUID;

import javax.annotation.Nullable;

public class BukkitCommandSender implements Actor {
public class BukkitCommandSender extends AbstractNonPlayerActor {

/**
* One time generated ID.
@@ -98,11 +96,6 @@ public void print(Component component) {
TextAdapter.sendComponent(sender, component);
}

@Override
public boolean canDestroyBedrock() {
return true;
}

@Override
public String[] getGroups() {
return new String[0];
@@ -117,42 +110,23 @@ public boolean hasPermission(String perm) {
public void checkPermission(String permission) throws AuthorizationException {
}

@Override
public boolean isPlayer() {
return false;
}

@Override
public File openFileOpenDialog(String[] extensions) {
return null;
}

@Override
public File openFileSaveDialog(String[] extensions) {
return null;
}

@Override
public void dispatchCUIEvent(CUIEvent event) {
}

@Override
public SessionKey getSessionKey() {
return new SessionKey() {
@Nullable
@Override
public String getName() {
return null;
return sender.getName();
}

@Override
public boolean isActive() {
return false;
return true;
}

@Override
public boolean isPersistent() {
return false;
return true;
}

@Override
@@ -32,6 +32,7 @@
public class BukkitConfiguration extends YAMLConfiguration {

public boolean noOpPermissions = false;
public boolean commandBlockSupport = false;
@Unreported private final WorldEditPlugin plugin;

public BukkitConfiguration(YAMLProcessor config, WorldEditPlugin plugin) {
@@ -43,6 +44,7 @@ public BukkitConfiguration(YAMLProcessor config, WorldEditPlugin plugin) {
public void load() {
super.load();
noOpPermissions = config.getBoolean("no-op-permissions", false);
commandBlockSupport = config.getBoolean("command-block-support", false);
migrateLegacyFolders();
}

@@ -19,7 +19,6 @@

package com.sk89q.worldedit.bukkit;

import com.sk89q.worldedit.registry.Category;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.ItemCategoryRegistry;
import org.bukkit.Bukkit;
@@ -44,9 +43,4 @@
Tag<Material> tag = Bukkit.getTag(Tag.REGISTRY_ITEMS, new NamespacedKey(namespace, key), Material.class);
return getFromBukkitTag(tag);
}

@Override
public Set<ItemType> getAll(Category<ItemType> category) {
return getCategorisedByName(category.getId());
}
}
@@ -58,6 +58,7 @@
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import static com.google.common.base.Preconditions.checkNotNull;
@@ -159,6 +160,11 @@ public String getName() {
return getWorld().getName();
}

@Override
public String getId() {
return getWorld().getName().replace(" ", "_").toLowerCase(Locale.ROOT);
}

@Override
public Path getStoragePath() {
return getWorld().getWorldFolder().toPath();
@@ -56,6 +56,7 @@
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Biome;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
@@ -432,6 +433,8 @@ public BukkitPlayer wrapPlayer(Player player) {
public Actor wrapCommandSender(CommandSender sender) {
if (sender instanceof Player) {
return wrapPlayer((Player) sender);
} else if (config.commandBlockSupport && sender instanceof BlockCommandSender) {
return new BukkitBlockCommandSender(this, (BlockCommandSender) sender);
}

return new BukkitCommandSender(this, sender);
@@ -149,3 +149,4 @@ no-op-permissions: false
debug: false
show-help-on-first-use: true
server-side-cui: true
command-block-support: false
@@ -0,0 +1,33 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar

applyPlatformAndCoreConfiguration()
applyShadowConfiguration()

dependencies {
"compile"(project(":worldedit-core"))
"compile"("org.apache.logging.log4j:log4j-core:2.8.1")
"compile"("org.apache.logging.log4j:log4j-slf4j-impl:2.8.1")
"compile"("commons-cli:commons-cli:1.4")
}

tasks.named<Jar>("jar") {
manifest {
attributes(
"Implementation-Version" to project.version,
"Main-Class" to "com.sk89q.worldedit.cli.CLIWorldEdit"
)
}
}

tasks.named<ShadowJar>("shadowJar") {
dependencies {
include { true }
}
minimize {
exclude { true }
}
}

tasks.named("assemble").configure {
dependsOn("shadowJar")
}

0 comments on commit 0620478

Please sign in to comment.
You can’t perform that action at this time.