diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 84e32fd07..317dd17f4 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -22,7 +22,7 @@ package com.sk89q.worldedit.bukkit; import static com.google.common.base.Preconditions.checkNotNull; import com.boydti.fawe.beta.IChunkGet; -import com.boydti.fawe.bukkit.beta.BukkitGetBlocks; +import com.boydti.fawe.bukkit.adapter.mc1_14.BukkitGetBlocks_1_14; import com.boydti.fawe.config.Settings; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.EditSession; @@ -509,8 +509,13 @@ public class BukkitWorld extends AbstractWorld { return true; } + @Override + public void sendChunk(int X, int Z, int mask) { + + } + @Override public IChunkGet get(int chunkX, int chunkZ) { - return new BukkitGetBlocks(getWorldChecked(), chunkX, chunkZ, Settings.IMP.QUEUE.POOL); + return new BukkitGetBlocks_1_14(getWorldChecked(), chunkX, chunkZ, Settings.IMP.QUEUE.POOL); } } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index 59b0217bf..d56e7fc63 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -21,9 +21,9 @@ package com.sk89q.worldedit.bukkit; import com.boydti.fawe.Fawe; import com.boydti.fawe.bukkit.FaweBukkit; -import com.boydti.fawe.bukkit.v1_14.adapter.Spigot_v1_14_R1; import com.boydti.fawe.util.MainUtil; +import com.boydti.fawe.bukkit.adapter.mc1_14.Spigot_v1_14_R1; import com.google.common.base.Joiner; import static com.google.common.base.Preconditions.checkNotNull; import com.sk89q.util.yaml.YAMLProcessor; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ApplyBrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ApplyBrushCommands.java index 48e3f8d66..823852c37 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ApplyBrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ApplyBrushCommands.java @@ -72,28 +72,6 @@ public class ApplyBrushCommands { .ofTypes(ImmutableList.of(Key.of(double.class))) .build(); - public static void register(CommandManagerService service, CommandManager commandManager, CommandRegistrationHandler registration) { - commandManager.register("apply", builder -> { - builder.description(TextComponent.of("Apply brush, apply a function to every block")); - builder.action(org.enginehub.piston.Command.Action.NULL_ACTION); - - CommandManager manager = service.newCommandManager(); - registration.register( - manager, - ApplyBrushCommandsRegistration.builder(), - new ApplyBrushCommands() - ); - - builder.condition(new PermissionCondition(ImmutableSet.of("worldedit.brush.apply"))); - - builder.addParts(REGION_FACTORY, RADIUS); - builder.addPart(SubCommandPart.builder(TranslatableComponent.of("type"), TextComponent.of("Type of brush to use")) - .withCommands(manager.getAllCommands().collect(Collectors.toList())) - .required() - .build()); - }); - } - private void setApplyBrush(CommandParameters parameters, Player player, LocalSession localSession, Contextual generatorFactory) throws WorldEditException { double radius = requireNonNull(RADIUS.value(parameters).asSingle(double.class)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index 92a8a0e60..3ea584ea9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -597,13 +597,13 @@ public class BrushCommands { @Command( name = "clipboard", - aliases = { "copy" }, - desc = "Choose the clipboard brush (Recommended: `/br copypaste`)", + desc = "@Deprecated use instead: `/br copypaste`)", descFooter = "Chooses the clipboard brush.\n" + "Without the -p flag, the paste will appear centered at the target location. " + "With the flag, then the paste will appear relative to where you had " + "stood relative to the copied area when you copied it." ) + @Deprecated @CommandPermissions("worldedit.brush.clipboard") public BrushSettings clipboardBrush(Player player,LocalSession session, @Switch(name = 'a', desc = "Don't paste air from the clipboard") diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/PaintBrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/PaintBrushCommands.java index 0cda0303b..348150638 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/PaintBrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/PaintBrushCommands.java @@ -77,28 +77,6 @@ public class PaintBrushCommands { .ofTypes(ImmutableList.of(Key.of(double.class))) .build(); - public static void register(CommandManagerService service, CommandManager commandManager, CommandRegistrationHandler registration) { - commandManager.register("paint", builder -> { - builder.description(TextComponent.of("Paint brush, apply a function to a surface")); - builder.action(org.enginehub.piston.Command.Action.NULL_ACTION); - - CommandManager manager = service.newCommandManager(); - registration.register( - manager, - PaintBrushCommandsRegistration.builder(), - new PaintBrushCommands() - ); - - builder.condition(new PermissionCondition(ImmutableSet.of("worldedit.brush.paint"))); - - builder.addParts(REGION_FACTORY, RADIUS, DENSITY); - builder.addPart(SubCommandPart.builder(TranslatableComponent.of("type"), TextComponent.of("Type of brush to use")) - .withCommands(manager.getAllCommands().collect(Collectors.toList())) - .required() - .build()); - }); - } - private void setPaintBrush(CommandParameters parameters, Player player, LocalSession localSession, Contextual generatorFactory) throws WorldEditException { double radius = requireNonNull(RADIUS.value(parameters).asSingle(double.class)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java index e1fc2512e..29bb01a2a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java @@ -33,14 +33,18 @@ import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.task.ThrowableSupplier; import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper; +import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Multimap; +import com.google.common.collect.SetMultimap; import com.google.common.reflect.TypeToken; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.command.ApplyBrushCommands; +import com.sk89q.worldedit.command.ApplyBrushCommandsRegistration; import com.sk89q.worldedit.command.BiomeCommands; import com.sk89q.worldedit.command.BiomeCommandsRegistration; import com.sk89q.worldedit.command.BrushCommands; @@ -61,6 +65,7 @@ import com.sk89q.worldedit.command.HistoryCommandsRegistration; import com.sk89q.worldedit.command.NavigationCommands; import com.sk89q.worldedit.command.NavigationCommandsRegistration; import com.sk89q.worldedit.command.PaintBrushCommands; +import com.sk89q.worldedit.command.PaintBrushCommandsRegistration; import com.sk89q.worldedit.command.PatternCommands; import com.sk89q.worldedit.command.PatternCommandsRegistration; import com.sk89q.worldedit.command.RegionCommands; @@ -131,13 +136,19 @@ import java.io.File; import java.io.IOException; import java.lang.annotation.Annotation; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.concurrent.Callable; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; import java.util.function.Consumer; +import java.util.function.Function; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.regex.Pattern; @@ -194,6 +205,7 @@ public final class PlatformCommandManager { private final DynamicStreamHandler dynamicHandler = new DynamicStreamHandler(); private final WorldEditExceptionConverter exceptionConverter; public final CommandRegistrationHandler registration; + private static PlatformCommandManager INSTANCE; /** @@ -267,45 +279,74 @@ public final class PlatformCommandManager { // TODO NOT IMPLEMENTED - register the following using a custom processor / annotations } - private void registerSubCommands(String name, List aliases, String desc, - CommandRegistration registration, CI instance) { - registerSubCommands(name, aliases, desc, registration, instance, m -> {}); + public org.enginehub.piston.annotation.Command createAnnotation(String name, List aliases, String desc) { + return new org.enginehub.piston.annotation.Command() { + @Override + public Class annotationType() { + return getClass(); + } + + @Override + public String name() { + return name; + } + + @Override + public String[] aliases() { + return aliases.toArray(new String[0]); + } + + @Override + public String desc() { + return desc; + } + + @Override + public String descFooter() { + return ""; + } + }; } - private void registerSubCommands(String name, List aliases, String desc, - CommandRegistration registration, CI instance, - Consumer additionalConfig) { - commandManager.register(name, cmd -> { - cmd.aliases(aliases); - cmd.description(TextComponent.of(desc)); - cmd.action(Command.Action.NULL_ACTION); + public void registerSubCommands(org.enginehub.piston.annotation.Command annotation, Consumer> handlerInstance) { + registerSubCommands(annotation, commandManager, handlerInstance); + } + + public void registerSubCommands(org.enginehub.piston.annotation.Command annotation, CommandManager commandManager, Consumer> handlerInstance) { + commandManager.register(annotation.name(), builder -> { + builder.description(TextComponent.of(annotation.desc())); + builder.action(org.enginehub.piston.Command.Action.NULL_ACTION); CommandManager manager = commandManagerService.newCommandManager(); - this.registration.register( - manager, - registration, - instance - ); - additionalConfig.accept(manager); + + handlerInstance.accept((handler, instance) -> registration.register( + manager, + handler, + instance + )); final List subCommands = manager.getAllCommands().collect(Collectors.toList()); - cmd.addPart(SubCommandPart.builder(TranslatableComponent.of("worldedit.argument.action"), - TextComponent.of("Sub-command to run.")) - .withCommands(subCommands) - .required() - .build()); + builder.addPart(SubCommandPart.builder(TranslatableComponent.of("worldedit.argument.action"), + TextComponent.of("Sub-command to run.")) + .withCommands(subCommands) + .required() + .build()); - cmd.condition(new SubCommandPermissionCondition.Generator(subCommands).build()); + builder.condition(new SubCommandPermissionCondition.Generator(subCommands).build()); }); } - public void getCommand(String arguments) { + public void registerSubCommands(String name, List aliases, String desc, + CommandRegistration registration, CI instance) { + registerSubCommands(createAnnotation(name, aliases, desc), commandManager, c -> c.accept(registration, instance)); + } + public void registerSubCommands(String name, List aliases, String desc, Consumer> handlerInstance) { + registerSubCommands(createAnnotation(name, aliases, desc), commandManager, handlerInstance); } public void registerAllCommands() { if (Settings.IMP.ENABLED_COMPONENTS.COMMANDS) { - // TODO NOT IMPLEMENTED dunno why these have issues generating registerSubCommands( "patterns", ImmutableList.of(), @@ -342,19 +383,16 @@ public final class PlatformCommandManager { new SuperPickaxeCommands(worldEdit) ); registerSubCommands( - "brush", - ImmutableList.of("br", "/brush", "/br"), - "Brushing commands", - BrushCommandsRegistration.builder(), - new BrushCommands(worldEdit), - manager -> { - PaintBrushCommands.register(commandManagerService, manager, registration); - ApplyBrushCommands.register(commandManagerService, manager, registration); + createAnnotation("brush", Arrays.asList("br", "/brush", "/br", "/tool", "tool"), "Brushing commands"), + c -> { + c.accept(BrushCommandsRegistration.builder(), new BrushCommands(worldEdit)); + c.accept(PaintBrushCommandsRegistration.builder(), new PaintBrushCommands()); + c.accept(ApplyBrushCommandsRegistration.builder(), new ApplyBrushCommands()); } ); registerSubCommands( "brush", - ImmutableList.of("br", "/b"), + ImmutableList.of("br", "/brush", "/br", "/tool", "tool"), "Tool commands", BrushOptionsCommandsRegistration.builder(), new BrushOptionsCommands(worldEdit) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/NamespacedRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/NamespacedRegistry.java index 6c86fdb0c..b5e83ff17 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/NamespacedRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/NamespacedRegistry.java @@ -19,29 +19,44 @@ package com.sk89q.worldedit.registry; +import com.google.common.collect.Maps; + import static com.google.common.base.Preconditions.checkState; import static java.util.Objects.requireNonNull; +import static org.enginehub.piston.converter.SuggestionHelper.byPrefix; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Stream; import javax.annotation.Nullable; -public final class NamespacedRegistry extends Registry { +public final class NamespacedRegistry extends Registry { private static final String MINECRAFT_NAMESPACE = "minecraft"; private final Set knownNamespaces = new HashSet<>(); private final String defaultNamespace; private final List values = new ArrayList<>(); private int lastInternalId = 0; + public NamespacedRegistry(final String name, Map map) { + this(name, map, MINECRAFT_NAMESPACE); + } + public NamespacedRegistry(final String name) { this(name, MINECRAFT_NAMESPACE); } public NamespacedRegistry(final String name, final String defaultNamespace) { - super(name); + this(name, Maps.newHashMap(), defaultNamespace); + } + + public NamespacedRegistry(final String name, Map map, final String defaultNamespace) { + super(name, map); this.defaultNamespace = defaultNamespace; } @@ -60,7 +75,9 @@ public final class NamespacedRegistry extends Re if (existing != null) { throw new UnsupportedOperationException("Replacing existing registrations is not supported"); } - value.setInternalId(lastInternalId++); + if (value instanceof RegistryItem) { + ((RegistryItem) value).setInternalId(lastInternalId++); + } values.add(value); super.register(key, value); if (key.startsWith(defaultNamespace)) { @@ -77,10 +94,6 @@ public final class NamespacedRegistry extends Re } } - public int getInternalId(V value) { - return value.getInternalId(); - } - public int size() { return values.size(); } @@ -109,4 +122,32 @@ public final class NamespacedRegistry extends Re } return key; } + + @Override + public Stream getSuggestions(String input) { + if (input.isEmpty() || input.equals(":")) { + final Set namespaces = getKnownNamespaces(); + if (namespaces.size() == 1) { + return keySet().stream(); + } else { + return namespaces.stream().map(s -> s + ":"); + } + } + if (input.startsWith(":")) { // special case - search across namespaces + final String term = input.substring(1).toLowerCase(Locale.ROOT); + Predicate search = byPrefix(term); + return keySet().stream().filter(s -> search.test(s.substring(s.indexOf(':') + 1))); + } + // otherwise, we actually have some text to search + if (input.indexOf(':') < 0) { + // don't yet have namespace - search namespaces + default + final String lowerSearch = input.toLowerCase(Locale.ROOT); + String defKey = getDefaultNamespace() + ":" + lowerSearch; + return Stream.concat(keySet().stream().filter(s -> s.startsWith(defKey)), + getKnownNamespaces().stream().filter(n -> n.startsWith(lowerSearch)).map(n -> n + ":")); + } + // have a namespace - search that + Predicate search = byPrefix(input.toLowerCase(Locale.ROOT)); + return keySet().stream().filter(search); + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java index 4a705ff7b..eb44b59d1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java @@ -293,6 +293,16 @@ public interface World extends Extent, Keyed, IChunkCache { return getName().replace(" ", "_").toLowerCase(Locale.ROOT); } + /** + * Refresh a specific chunk with a bitMask (0 = default, 65535 = all block sections) + * Note: only 0 is guaranteed to send all tiles / entities + * Note: Only 65535 is guaranteed to send all blocks + * @param chunkX + * @param chunkZ + * @param bitMask + */ + void sendChunk(final int X, final int Z, final int mask); + @Override IChunkGet get(int x, int z); }