Multi clipboard pattern
This commit is contained in:
parent
b56f6664d5
commit
b20120a1f2
@ -39,6 +39,7 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
|||||||
public static BukkitImplAdapter adapter;
|
public static BukkitImplAdapter adapter;
|
||||||
public static Method methodToNative;
|
public static Method methodToNative;
|
||||||
public static Method methodFromNative;
|
public static Method methodFromNative;
|
||||||
|
private static boolean setupAdapter = false;
|
||||||
|
|
||||||
public BukkitQueue_0(final com.sk89q.worldedit.world.World world) {
|
public BukkitQueue_0(final com.sk89q.worldedit.world.World world) {
|
||||||
super(world);
|
super(world);
|
||||||
@ -137,6 +138,9 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
|||||||
|
|
||||||
public static void setupAdapter(BukkitImplAdapter adapter) {
|
public static void setupAdapter(BukkitImplAdapter adapter) {
|
||||||
try {
|
try {
|
||||||
|
if (setupAdapter == (setupAdapter = true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
WorldEditPlugin instance = (WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit");
|
WorldEditPlugin instance = (WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit");
|
||||||
Field fieldAdapter = WorldEditPlugin.class.getDeclaredField("bukkitAdapter");
|
Field fieldAdapter = WorldEditPlugin.class.getDeclaredField("bukkitAdapter");
|
||||||
fieldAdapter.setAccessible(true);
|
fieldAdapter.setAccessible(true);
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.boydti.fawe.object.clipboard;
|
||||||
|
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||||
|
import com.sk89q.worldedit.world.registry.WorldData;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class RandomClipboardHolder extends LazyClipboardHolder {
|
||||||
|
public RandomClipboardHolder(ByteSource source, ClipboardFormat format, WorldData worldData, UUID uuid) {
|
||||||
|
super(source, format, worldData, uuid);
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ package com.boydti.fawe.object.pattern;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.MutableBlockVector;
|
import com.sk89q.worldedit.MutableBlockVector;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
@ -20,8 +21,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
public class FullClipboardPattern extends AbstractPattern {
|
public class FullClipboardPattern extends AbstractPattern {
|
||||||
private final Extent extent;
|
private final Extent extent;
|
||||||
private final Clipboard clipboard;
|
private final Clipboard clipboard;
|
||||||
private final BaseBlock block;
|
|
||||||
|
|
||||||
private final MutableBlockVector mutable = new MutableBlockVector();
|
private final MutableBlockVector mutable = new MutableBlockVector();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,16 +32,19 @@ public class FullClipboardPattern extends AbstractPattern {
|
|||||||
checkNotNull(clipboard);
|
checkNotNull(clipboard);
|
||||||
this.clipboard = clipboard;
|
this.clipboard = clipboard;
|
||||||
this.extent = extent;
|
this.extent = extent;
|
||||||
Vector origin = clipboard.getOrigin();
|
|
||||||
block = clipboard.getBlock(origin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseBlock apply(Vector to) {
|
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||||
Region region = clipboard.getRegion();
|
Region region = clipboard.getRegion();
|
||||||
ForwardExtentCopy copy = new ForwardExtentCopy(clipboard, clipboard.getRegion(), clipboard.getOrigin(), extent, to);
|
ForwardExtentCopy copy = new ForwardExtentCopy(clipboard, clipboard.getRegion(), clipboard.getOrigin(), extent, setPosition);
|
||||||
copy.setSourceMask(new ExistingBlockMask(clipboard));
|
copy.setSourceMask(new ExistingBlockMask(clipboard));
|
||||||
Operations.completeBlindly(copy);
|
Operations.completeBlindly(copy);
|
||||||
return block;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock apply(Vector position) {
|
||||||
|
throw new IllegalStateException("Incorrect use. This pattern can only be applied to an extent!");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package com.boydti.fawe.object.pattern;
|
||||||
|
|
||||||
|
import com.boydti.fawe.object.PseudoRandom;
|
||||||
|
import com.boydti.fawe.object.schematic.Schematic;
|
||||||
|
import com.sk89q.worldedit.MutableBlockVector;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
|
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||||
|
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||||
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
|
import com.sk89q.worldedit.world.registry.WorldData;
|
||||||
|
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
public class RandomFullClipboardPattern extends AbstractPattern {
|
||||||
|
private final Extent extent;
|
||||||
|
private final ClipboardHolder[] clipboards;
|
||||||
|
private final MutableBlockVector mutable = new MutableBlockVector();
|
||||||
|
private boolean randomRotate;
|
||||||
|
private WorldData worldData;
|
||||||
|
|
||||||
|
public RandomFullClipboardPattern(Extent extent, WorldData worldData, ClipboardHolder[] clipboards, boolean randomRotate) {
|
||||||
|
checkNotNull(clipboards);
|
||||||
|
this.clipboards = clipboards;
|
||||||
|
this.extent = extent;
|
||||||
|
this.randomRotate = randomRotate;
|
||||||
|
this.worldData = worldData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||||
|
ClipboardHolder holder = clipboards[PseudoRandom.random.random(clipboards.length)];
|
||||||
|
if (randomRotate) {
|
||||||
|
holder.setTransform(new AffineTransform().rotateY(PseudoRandom.random.random(4) * 90));
|
||||||
|
}
|
||||||
|
Clipboard clipboard = holder.getClipboard();
|
||||||
|
Schematic schematic = new Schematic(clipboard);
|
||||||
|
if (holder.getTransform().isIdentity()) {
|
||||||
|
schematic.paste(extent, setPosition, false);
|
||||||
|
} else {
|
||||||
|
schematic.paste(extent, worldData, setPosition, false, holder.getTransform());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseBlock apply(Vector position) {
|
||||||
|
throw new IllegalStateException("Incorrect use. This pattern can only be applied to an extent!");
|
||||||
|
}
|
||||||
|
}
|
@ -1,24 +1,34 @@
|
|||||||
package com.boydti.fawe.object.schematic;
|
package com.boydti.fawe.object.schematic;
|
||||||
|
|
||||||
|
import com.boydti.fawe.object.HasFaweQueue;
|
||||||
|
import com.boydti.fawe.object.RunnableVal2;
|
||||||
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
|
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
|
||||||
import com.boydti.fawe.util.EditSessionBuilder;
|
import com.boydti.fawe.util.EditSessionBuilder;
|
||||||
import com.boydti.fawe.util.MaskTraverser;
|
import com.boydti.fawe.util.MaskTraverser;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
||||||
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
||||||
|
import com.sk89q.worldedit.function.RegionFunction;
|
||||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||||
import com.sk89q.worldedit.function.operation.Operations;
|
import com.sk89q.worldedit.function.operation.Operations;
|
||||||
|
import com.sk89q.worldedit.function.visitor.RegionVisitor;
|
||||||
import com.sk89q.worldedit.math.transform.Transform;
|
import com.sk89q.worldedit.math.transform.Transform;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.util.Location;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
|
import com.sk89q.worldedit.world.registry.WorldData;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -133,4 +143,77 @@ public class Schematic {
|
|||||||
editSession.flushQueue();
|
editSession.flushQueue();
|
||||||
return editSession;
|
return editSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void paste(Extent extent, WorldData worldData, Vector to, boolean pasteAir, Transform transform) {
|
||||||
|
Region region = clipboard.getRegion();
|
||||||
|
BlockTransformExtent source = new BlockTransformExtent(clipboard, transform, worldData.getBlockRegistry());
|
||||||
|
ForwardExtentCopy copy = new ForwardExtentCopy(source, clipboard.getRegion(), clipboard.getOrigin(), extent, to);
|
||||||
|
copy.setTransform(transform);
|
||||||
|
if (!pasteAir) {
|
||||||
|
copy.setSourceMask(new ExistingBlockMask(clipboard));
|
||||||
|
}
|
||||||
|
Operations.completeBlindly(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paste(Extent extent, Vector to, boolean pasteAir) {
|
||||||
|
Region region = clipboard.getRegion().clone();
|
||||||
|
final int maxY = extent.getMaximumPoint().getBlockY();
|
||||||
|
final Vector bot = clipboard.getMinimumPoint();
|
||||||
|
final Vector origin = clipboard.getOrigin();
|
||||||
|
// Optimize for BlockArrayClipboard
|
||||||
|
if (clipboard instanceof BlockArrayClipboard && region instanceof CuboidRegion) {
|
||||||
|
// To is relative to the world origin (player loc + small clipboard offset) (As the positions supplied are relative to the clipboard min)
|
||||||
|
final int relx = to.getBlockX() + bot.getBlockX() - origin.getBlockX();
|
||||||
|
final int rely = to.getBlockY() + bot.getBlockY() - origin.getBlockY();
|
||||||
|
final int relz = to.getBlockZ() + bot.getBlockZ() - origin.getBlockZ();
|
||||||
|
BlockArrayClipboard bac = (BlockArrayClipboard) clipboard;
|
||||||
|
bac.IMP.forEach(new RunnableVal2<Vector, BaseBlock>() {
|
||||||
|
@Override
|
||||||
|
public void run(Vector mutable, BaseBlock block) {
|
||||||
|
mutable.mutX(mutable.getX() + relx);
|
||||||
|
mutable.mutY(mutable.getY() + rely);
|
||||||
|
mutable.mutZ(mutable.getZ() + relz);
|
||||||
|
if (mutable.getY() >= 0 && mutable.getY() <= maxY) {
|
||||||
|
try {
|
||||||
|
extent.setBlock(mutable, block);
|
||||||
|
} catch (WorldEditException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, pasteAir);
|
||||||
|
} else {
|
||||||
|
// To must be relative to the clipboard origin ( player location - clipboard origin ) (as the locations supplied are relative to the world origin)
|
||||||
|
final int relx = to.getBlockX() - origin.getBlockX();
|
||||||
|
final int rely = to.getBlockY() - origin.getBlockY();
|
||||||
|
final int relz = to.getBlockZ() - origin.getBlockZ();
|
||||||
|
RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(Vector mutable) throws WorldEditException {
|
||||||
|
BaseBlock block = clipboard.getBlock(mutable);
|
||||||
|
if (block == EditSession.nullBlock && !pasteAir) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mutable.mutX(mutable.getX() + relx);
|
||||||
|
mutable.mutY(mutable.getY() + rely);
|
||||||
|
mutable.mutZ(mutable.getZ() + relz);
|
||||||
|
if (mutable.getY() >= 0 && mutable.getY() <= maxY) {
|
||||||
|
return extent.setBlock(mutable, block);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, (HasFaweQueue) (extent instanceof HasFaweQueue ? extent : null));
|
||||||
|
Operations.completeBlindly(visitor);
|
||||||
|
}
|
||||||
|
// Entity offset is the paste location subtract the clipboard origin (entity's location is already relative to the world origin)
|
||||||
|
final int entityOffsetX = to.getBlockX() - origin.getBlockX();
|
||||||
|
final int entityOffsetY = to.getBlockY() - origin.getBlockY();
|
||||||
|
final int entityOffsetZ = to.getBlockZ() - origin.getBlockZ();
|
||||||
|
// entities
|
||||||
|
for (Entity entity : clipboard.getEntities()) {
|
||||||
|
Location pos = entity.getLocation();
|
||||||
|
Location newPos = new Location(pos.getExtent(), pos.getX() + entityOffsetX, pos.getY() + entityOffsetY, pos.getZ() + entityOffsetZ, pos.getYaw(), pos.getPitch());
|
||||||
|
extent.createEntity(newPos, entity.getState());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,12 +50,8 @@ import com.boydti.fawe.object.brush.scroll.ScrollRange;
|
|||||||
import com.boydti.fawe.object.brush.scroll.ScrollSize;
|
import com.boydti.fawe.object.brush.scroll.ScrollSize;
|
||||||
import com.boydti.fawe.object.brush.scroll.ScrollTarget;
|
import com.boydti.fawe.object.brush.scroll.ScrollTarget;
|
||||||
import com.boydti.fawe.object.brush.visualization.VisualMode;
|
import com.boydti.fawe.object.brush.visualization.VisualMode;
|
||||||
import com.boydti.fawe.object.clipboard.LazyClipboardHolder;
|
|
||||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
|
||||||
import com.boydti.fawe.object.mask.IdMask;
|
import com.boydti.fawe.object.mask.IdMask;
|
||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.google.common.io.ByteSource;
|
|
||||||
import com.google.common.io.Files;
|
|
||||||
import com.sk89q.minecraft.util.commands.Command;
|
import com.sk89q.minecraft.util.commands.Command;
|
||||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||||
@ -93,9 +89,7 @@ import com.sk89q.worldedit.function.pattern.Pattern;
|
|||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||||
import com.sk89q.worldedit.world.registry.WorldData;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileFilter;
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -103,10 +97,6 @@ import java.io.InputStream;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.nio.channels.ReadableByteChannel;
|
import java.nio.channels.ReadableByteChannel;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipInputStream;
|
|
||||||
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -237,71 +227,11 @@ public class BrushCommands {
|
|||||||
}
|
}
|
||||||
String filename = args.getString(1);
|
String filename = args.getString(1);
|
||||||
try {
|
try {
|
||||||
WorldData worldData = player.getWorld().getWorldData();
|
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), filename, true);
|
||||||
if (filename.startsWith("http")) {
|
if (clipboards == null) {
|
||||||
URL url = new URL(filename);
|
return;
|
||||||
URL webInterface = new URL(Settings.IMP.WEB.ASSETS);
|
|
||||||
if (!url.getHost().equalsIgnoreCase(webInterface.getHost())) {
|
|
||||||
BBC.WEB_UNAUTHORIZED.send(player, url);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
List<LazyClipboardHolder> clipboards = new ArrayList<>();
|
|
||||||
try (ReadableByteChannel rbc = Channels.newChannel(url.openStream())) {
|
|
||||||
try (InputStream in = Channels.newInputStream(rbc)) {
|
|
||||||
try (ZipInputStream zip = new ZipInputStream(in)) {
|
|
||||||
ZipEntry entry;
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
while ((entry = zip.getNextEntry()) != null) {
|
|
||||||
if (entry.getName().endsWith(".schematic")) {
|
|
||||||
FastByteArrayOutputStream out = new FastByteArrayOutputStream();
|
|
||||||
int len = 0;
|
|
||||||
while ((len = zip.read(buffer)) > 0) {
|
|
||||||
out.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
byte[] array = out.toByteArray();
|
|
||||||
ByteSource source = ByteSource.wrap(array);
|
|
||||||
LazyClipboardHolder clipboard = new LazyClipboardHolder(source, ClipboardFormat.SCHEMATIC, worldData, null);
|
|
||||||
clipboards.add(clipboard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tool.setScrollAction(new ScrollClipboard(tool, session, clipboards.toArray(new LazyClipboardHolder[clipboards.size()])));
|
|
||||||
} else {
|
|
||||||
if (filename.contains("../") && !player.hasPermission("worldedit.schematic.load.other")) {
|
|
||||||
BBC.NO_PERM.send(player, "worldedit.schematic.load.other");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
File working = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
|
||||||
File dir = new File(working, (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? (player.getUniqueId().toString() + File.separator) : "") + filename);
|
|
||||||
if (!dir.exists()) {
|
|
||||||
if ((!filename.contains("/") && !filename.contains("\\")) || player.hasPermission("worldedit.schematic.load.other")) {
|
|
||||||
dir = new File(this.worldEdit.getWorkingDirectoryFile(config.saveDir), filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!dir.exists() || !dir.isDirectory()) {
|
|
||||||
BBC.SCHEMATIC_NOT_FOUND.send(player, filename);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
File[] files = dir.listFiles(new FileFilter() {
|
|
||||||
@Override
|
|
||||||
public boolean accept(File pathname) {
|
|
||||||
return pathname.getName().endsWith(".schematic");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (files.length < 1) {
|
|
||||||
BBC.SCHEMATIC_NOT_FOUND.send(player, filename);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LazyClipboardHolder[] clipboards = new LazyClipboardHolder[files.length];
|
|
||||||
for (int i = 0; i < files.length; i++) {
|
|
||||||
File file = files[i];
|
|
||||||
ByteSource source = Files.asByteSource(file);
|
|
||||||
clipboards[i] = new LazyClipboardHolder(source, ClipboardFormat.SCHEMATIC, worldData, null);
|
|
||||||
}
|
|
||||||
tool.setScrollAction(new ScrollClipboard(tool, session, clipboards));
|
|
||||||
}
|
}
|
||||||
|
tool.setScrollAction(new ScrollClipboard(tool, session, clipboards));
|
||||||
break;
|
break;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
@ -24,11 +24,11 @@ import com.boydti.fawe.config.BBC;
|
|||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.FaweLimit;
|
import com.boydti.fawe.object.FaweLimit;
|
||||||
import com.boydti.fawe.object.FawePlayer;
|
import com.boydti.fawe.object.FawePlayer;
|
||||||
import com.boydti.fawe.object.RunnableVal2;
|
|
||||||
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
|
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
|
||||||
import com.boydti.fawe.object.clipboard.WorldCutClipboard;
|
import com.boydti.fawe.object.clipboard.WorldCutClipboard;
|
||||||
import com.boydti.fawe.object.exception.FaweException;
|
import com.boydti.fawe.object.exception.FaweException;
|
||||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||||
|
import com.boydti.fawe.object.schematic.Schematic;
|
||||||
import com.boydti.fawe.util.ImgurUtility;
|
import com.boydti.fawe.util.ImgurUtility;
|
||||||
import com.boydti.fawe.util.MaskTraverser;
|
import com.boydti.fawe.util.MaskTraverser;
|
||||||
import com.sk89q.minecraft.util.commands.Command;
|
import com.sk89q.minecraft.util.commands.Command;
|
||||||
@ -40,14 +40,11 @@ import com.sk89q.worldedit.LocalSession;
|
|||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
||||||
import com.sk89q.worldedit.function.RegionFunction;
|
|
||||||
import com.sk89q.worldedit.function.block.BlockReplace;
|
import com.sk89q.worldedit.function.block.BlockReplace;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.mask.Masks;
|
import com.sk89q.worldedit.function.mask.Masks;
|
||||||
@ -55,17 +52,14 @@ import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
|||||||
import com.sk89q.worldedit.function.operation.Operation;
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
import com.sk89q.worldedit.function.operation.Operations;
|
import com.sk89q.worldedit.function.operation.Operations;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.function.visitor.RegionVisitor;
|
|
||||||
import com.sk89q.worldedit.internal.annotation.Direction;
|
import com.sk89q.worldedit.internal.annotation.Direction;
|
||||||
import com.sk89q.worldedit.internal.annotation.Selection;
|
import com.sk89q.worldedit.internal.annotation.Selection;
|
||||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||||
import com.sk89q.worldedit.math.transform.Transform;
|
import com.sk89q.worldedit.math.transform.Transform;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.regions.RegionSelector;
|
import com.sk89q.worldedit.regions.RegionSelector;
|
||||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.util.Location;
|
|
||||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -373,7 +367,6 @@ public class ClipboardCommands {
|
|||||||
place(player, session, editSession, ignoreAirBlocks, atOrigin, selectPasted);
|
place(player, session, editSession, ignoreAirBlocks, atOrigin, selectPasted);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Clipboard clipboard = holder.getClipboard();
|
Clipboard clipboard = holder.getClipboard();
|
||||||
Region region = clipboard.getRegion();
|
Region region = clipboard.getRegion();
|
||||||
Vector to = atOrigin ? clipboard.getOrigin() : session.getPlacementPosition(player);
|
Vector to = atOrigin ? clipboard.getOrigin() : session.getPlacementPosition(player);
|
||||||
@ -420,63 +413,13 @@ public class ClipboardCommands {
|
|||||||
@Switch('s') boolean selectPasted) throws WorldEditException {
|
@Switch('s') boolean selectPasted) throws WorldEditException {
|
||||||
ClipboardHolder holder = session.getClipboard();
|
ClipboardHolder holder = session.getClipboard();
|
||||||
final Clipboard clipboard = holder.getClipboard();
|
final Clipboard clipboard = holder.getClipboard();
|
||||||
Region region = clipboard.getRegion().clone();
|
|
||||||
|
|
||||||
final int maxY = editSession.getMaxY();
|
|
||||||
final Vector bot = clipboard.getMinimumPoint();
|
|
||||||
final Vector origin = clipboard.getOrigin();
|
final Vector origin = clipboard.getOrigin();
|
||||||
final Vector to = atOrigin ? origin : session.getPlacementPosition(player);
|
final Vector to = atOrigin ? origin : session.getPlacementPosition(player);
|
||||||
// Optimize for BlockArrayClipboard
|
|
||||||
if (clipboard instanceof BlockArrayClipboard && region instanceof CuboidRegion) {
|
Schematic schem = new Schematic(clipboard);
|
||||||
// To is relative to the world origin (player loc + small clipboard offset) (As the positions supplied are relative to the clipboard min)
|
schem.paste(editSession, to, !ignoreAirBlocks);
|
||||||
final int relx = to.getBlockX() + bot.getBlockX() - origin.getBlockX();
|
|
||||||
final int rely = to.getBlockY() + bot.getBlockY() - origin.getBlockY();
|
Region region = clipboard.getRegion().clone();
|
||||||
final int relz = to.getBlockZ() + bot.getBlockZ() - origin.getBlockZ();
|
|
||||||
BlockArrayClipboard bac = (BlockArrayClipboard) clipboard;
|
|
||||||
bac.IMP.forEach(new RunnableVal2<Vector, BaseBlock>() {
|
|
||||||
@Override
|
|
||||||
public void run(Vector mutable, BaseBlock block) {
|
|
||||||
mutable.mutX(mutable.getX() + relx);
|
|
||||||
mutable.mutY(mutable.getY() + rely);
|
|
||||||
mutable.mutZ(mutable.getZ() + relz);
|
|
||||||
if (mutable.getY() >= 0 && mutable.getY() <= maxY) {
|
|
||||||
editSession.setBlockFast(mutable, block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, !ignoreAirBlocks);
|
|
||||||
} else {
|
|
||||||
// To must be relative to the clipboard origin ( player location - clipboard origin ) (as the locations supplied are relative to the world origin)
|
|
||||||
final int relx = to.getBlockX() - origin.getBlockX();
|
|
||||||
final int rely = to.getBlockY() - origin.getBlockY();
|
|
||||||
final int relz = to.getBlockZ() - origin.getBlockZ();
|
|
||||||
RegionVisitor visitor = new RegionVisitor(region, new RegionFunction() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(Vector mutable) throws WorldEditException {
|
|
||||||
BaseBlock block = clipboard.getBlock(mutable);
|
|
||||||
if (block == EditSession.nullBlock && ignoreAirBlocks) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
mutable.mutX(mutable.getX() + relx);
|
|
||||||
mutable.mutY(mutable.getY() + rely);
|
|
||||||
mutable.mutZ(mutable.getZ() + relz);
|
|
||||||
if (mutable.getY() >= 0 && mutable.getY() <= maxY) {
|
|
||||||
return editSession.setBlockFast(mutable, block);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}, editSession);
|
|
||||||
Operations.completeBlindly(visitor);
|
|
||||||
}
|
|
||||||
// Entity offset is the paste location subtract the clipboard origin (entity's location is already relative to the world origin)
|
|
||||||
final int entityOffsetX = to.getBlockX() - origin.getBlockX();
|
|
||||||
final int entityOffsetY = to.getBlockY() - origin.getBlockY();
|
|
||||||
final int entityOffsetZ = to.getBlockZ() - origin.getBlockZ();
|
|
||||||
// entities
|
|
||||||
for (Entity entity : clipboard.getEntities()) {
|
|
||||||
Location pos = entity.getLocation();
|
|
||||||
Location newPos = new Location(pos.getExtent(), pos.getX() + entityOffsetX, pos.getY() + entityOffsetY, pos.getZ() + entityOffsetZ, pos.getYaw(), pos.getPitch());
|
|
||||||
editSession.createEntity(newPos, entity.getState());
|
|
||||||
}
|
|
||||||
if (selectPasted) {
|
if (selectPasted) {
|
||||||
Vector max = to.add(region.getMaximumPoint().subtract(region.getMinimumPoint()));
|
Vector max = to.add(region.getMaximumPoint().subtract(region.getMinimumPoint()));
|
||||||
RegionSelector selector = new CuboidRegionSelector(player.getWorld(), to, max);
|
RegionSelector selector = new CuboidRegionSelector(player.getWorld(), to, max);
|
||||||
|
@ -2,7 +2,25 @@ package com.sk89q.worldedit.extension.factory;
|
|||||||
|
|
||||||
import com.boydti.fawe.command.FaweParser;
|
import com.boydti.fawe.command.FaweParser;
|
||||||
import com.boydti.fawe.command.SuggestInputParseException;
|
import com.boydti.fawe.command.SuggestInputParseException;
|
||||||
import com.boydti.fawe.object.pattern.*;
|
import com.boydti.fawe.object.pattern.BiomePattern;
|
||||||
|
import com.boydti.fawe.object.pattern.DataPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.ExistingPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.ExpressionPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.FullClipboardPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.IdPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.Linear3DBlockPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.LinearBlockPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.MaskedPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.NoXPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.NoYPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.NoZPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.OffsetPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.PatternExtent;
|
||||||
|
import com.boydti.fawe.object.pattern.RandomFullClipboardPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.RandomOffsetPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.RelativePattern;
|
||||||
|
import com.boydti.fawe.object.pattern.SolidRandomOffsetPattern;
|
||||||
|
import com.boydti.fawe.object.pattern.SurfaceRandomOffsetPattern;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.StringMan;
|
import com.boydti.fawe.util.StringMan;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
@ -14,6 +32,7 @@ import com.sk89q.worldedit.entity.Player;
|
|||||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||||
import com.sk89q.worldedit.function.pattern.ClipboardPattern;
|
import com.sk89q.worldedit.function.pattern.ClipboardPattern;
|
||||||
@ -29,6 +48,7 @@ import com.sk89q.worldedit.world.biome.BaseBiome;
|
|||||||
import com.sk89q.worldedit.world.biome.Biomes;
|
import com.sk89q.worldedit.world.biome.Biomes;
|
||||||
import com.sk89q.worldedit.world.registry.BiomeRegistry;
|
import com.sk89q.worldedit.world.registry.BiomeRegistry;
|
||||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -97,25 +117,13 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
|||||||
}
|
}
|
||||||
switch (input.toLowerCase().charAt(0)) {
|
switch (input.toLowerCase().charAt(0)) {
|
||||||
case '#': {
|
case '#': {
|
||||||
switch (input) {
|
String[] split2 = input.split(":");
|
||||||
|
String rest = split2.length > 1 ? input.substring(split2[0].length() + 1) : "";
|
||||||
|
switch (split2[0].toLowerCase()) {
|
||||||
case "#*":
|
case "#*":
|
||||||
case "#existing": {
|
case "#existing": {
|
||||||
return new ExistingPattern(Request.request().getEditSession());
|
return new ExistingPattern(Request.request().getEditSession());
|
||||||
}
|
}
|
||||||
case "#fullcopy": {
|
|
||||||
LocalSession session = context.requireSession();
|
|
||||||
if (session != null) {
|
|
||||||
try {
|
|
||||||
ClipboardHolder holder = session.getClipboard();
|
|
||||||
Clipboard clipboard = holder.getClipboard();
|
|
||||||
return new FullClipboardPattern(Request.request().getEditSession(), clipboard);
|
|
||||||
} catch (EmptyClipboardException e) {
|
|
||||||
throw new InputParseException("To use #fullcopy, please first copy something to your clipboard");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new InputParseException("No session is available, so no clipboard is available");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "#clipboard":
|
case "#clipboard":
|
||||||
case "#copy": {
|
case "#copy": {
|
||||||
LocalSession session = context.requireSession();
|
LocalSession session = context.requireSession();
|
||||||
@ -131,141 +139,163 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
|||||||
throw new InputParseException("No session is available, so no clipboard is available");
|
throw new InputParseException("No session is available, so no clipboard is available");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
case "#fullcopy": {
|
||||||
String[] split2 = input.split(":");
|
LocalSession session = context.requireSession();
|
||||||
if (split2.length > 1 || input.endsWith(":")) {
|
if (session != null) {
|
||||||
String rest = input.substring(split2[0].length() + 1);
|
|
||||||
switch (split2[0].toLowerCase()) {
|
|
||||||
case "#id": {
|
|
||||||
return new IdPattern(Request.request().getEditSession(), catchSuggestion(input, rest, context));
|
|
||||||
}
|
|
||||||
case "#data": {
|
|
||||||
return new DataPattern(Request.request().getEditSession(), catchSuggestion(input, rest, context));
|
|
||||||
}
|
|
||||||
case "#biome": {
|
|
||||||
World world = context.getWorld();
|
|
||||||
BiomeRegistry biomeRegistry = world.getWorldData().getBiomeRegistry();
|
|
||||||
List<BaseBiome> knownBiomes = biomeRegistry.getBiomes();
|
|
||||||
BaseBiome biome = Biomes.findBiomeByName(knownBiomes, rest, biomeRegistry);
|
|
||||||
return new BiomePattern(Request.request().getEditSession(), biome);
|
|
||||||
}
|
|
||||||
case "#~":
|
|
||||||
case "#r":
|
|
||||||
case "#relative":
|
|
||||||
case "#rel": {
|
|
||||||
return new RelativePattern(catchSuggestion(input, rest, context));
|
|
||||||
}
|
|
||||||
case "#!x":
|
|
||||||
case "#nx":
|
|
||||||
case "#nox": {
|
|
||||||
return new NoXPattern(catchSuggestion(input, rest, context));
|
|
||||||
}
|
|
||||||
case "#!y":
|
|
||||||
case "#ny":
|
|
||||||
case "#noy": {
|
|
||||||
return new NoYPattern(catchSuggestion(input, rest, context));
|
|
||||||
}
|
|
||||||
case "#!z":
|
|
||||||
case "#nz":
|
|
||||||
case "#noz": {
|
|
||||||
return new NoZPattern(catchSuggestion(input, rest, context));
|
|
||||||
}
|
|
||||||
case "#mask": {
|
|
||||||
List<String> split3 = suggestRemaining(rest, "#mask", "<mask>", "<pattern-if>", "<pattern-else>");
|
|
||||||
Pattern primary = catchSuggestion(input, split3.get(1), context);
|
|
||||||
Pattern secondary = catchSuggestion(input, split3.get(2), context);
|
|
||||||
PatternExtent extent = new PatternExtent(primary);
|
|
||||||
Request request = Request.request();
|
|
||||||
request.setExtent(extent);
|
|
||||||
request.setSession(context.getSession());
|
|
||||||
request.setWorld(context.getWorld());
|
|
||||||
context.setExtent(extent);
|
|
||||||
MaskFactory factory = worldEdit.getMaskFactory();
|
|
||||||
Mask mask = factory.parseFromInput(split3.get(0), context);
|
|
||||||
if (mask == null | primary == null || secondary == null) {
|
|
||||||
throw new SuggestInputParseException(null, "#mask:<mask>:<pattern-if>:<pattern-else>");
|
|
||||||
}
|
|
||||||
return new MaskedPattern(mask, extent, secondary);
|
|
||||||
}
|
|
||||||
case "#offset":
|
|
||||||
try {
|
try {
|
||||||
List<String> split3 = suggestRemaining(rest, "#offset", "<dx>", "<dy>", "<dz>", "<pattern>");
|
if (split2.length > 1) {
|
||||||
int x = (int) Expression.compile(split3.get(0)).evaluate();
|
String location = split2[1];
|
||||||
int y = (int) Expression.compile(split3.get(1)).evaluate();
|
try {
|
||||||
int z = (int) Expression.compile(split3.get(2)).evaluate();
|
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(context.getActor(), context.requireWorld().getWorldData(), location, true);
|
||||||
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
if (clipboards == null) {
|
||||||
Pattern pattern = catchSuggestion(input, rest, context);
|
System.out.println("NULL!");
|
||||||
return new OffsetPattern(pattern, x, y, z);
|
throw new InputParseException("#fullcopy:<source>");
|
||||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
}
|
||||||
throw new SuggestInputParseException(null, "#offset:<dx>:<dy>:<dz>:<pattern>");
|
boolean random = split2.length == 3 && split2[2].equalsIgnoreCase("true");
|
||||||
}
|
return new RandomFullClipboardPattern(Request.request().getEditSession(), context.requireWorld().getWorldData(), clipboards, random);
|
||||||
case "#surfacespread": {
|
|
||||||
try {
|
} catch (IOException e) {
|
||||||
List<String> split3 = suggestRemaining(rest, "#surfacespread", "<dx>", "<dy>", "<dz>", "<pattern>");
|
throw new RuntimeException(e);
|
||||||
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
}
|
||||||
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
}
|
||||||
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
ClipboardHolder holder = session.getClipboard();
|
||||||
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
Clipboard clipboard = holder.getClipboard();
|
||||||
Pattern pattern = catchSuggestion(input, rest, context);
|
return new FullClipboardPattern(Request.request().getEditSession(), clipboard);
|
||||||
return new SurfaceRandomOffsetPattern(pattern, x, y, z);
|
} catch (EmptyClipboardException e) {
|
||||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
throw new InputParseException("To use #fullcopy, please first copy something to your clipboard");
|
||||||
throw new SuggestInputParseException(null, "#surfacespread:<dx>:<dy>:<dz>:<pattern>");
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
throw new InputParseException("No session is available, so no clipboard is available");
|
||||||
}
|
}
|
||||||
case "#solidspread": {
|
|
||||||
try {
|
|
||||||
List<String> split3 = suggestRemaining(rest, "#solidspread", "<dx>", "<dy>", "<dz>", "<pattern>");
|
|
||||||
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
|
||||||
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
|
||||||
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
|
||||||
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
|
||||||
Pattern pattern = catchSuggestion(input, rest, context);
|
|
||||||
return new SolidRandomOffsetPattern(pattern, x, y, z);
|
|
||||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
|
||||||
throw new SuggestInputParseException(null, "#solidspread:<dx>:<dy>:<dz>:<pattern>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "#randomoffset":
|
|
||||||
case "#spread": {
|
|
||||||
try {
|
|
||||||
List<String> split3 = suggestRemaining(rest, "#spread", "<dx>", "<dy>", "<dz>", "<pattern>");
|
|
||||||
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
|
||||||
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
|
||||||
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
|
||||||
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
|
||||||
Pattern pattern = catchSuggestion(input, rest, context);
|
|
||||||
return new RandomOffsetPattern(pattern, x, y, z);
|
|
||||||
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
|
||||||
throw new SuggestInputParseException(null, "#spread:<dx>:<dy>:<dz>:<pattern>");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "#l":
|
|
||||||
case "#linear": {
|
|
||||||
ArrayList<Pattern> patterns = new ArrayList<>();
|
|
||||||
for (String token : StringMan.split(rest, ',')) {
|
|
||||||
patterns.add(catchSuggestion(input, token, context));
|
|
||||||
}
|
|
||||||
if (patterns.isEmpty()) {
|
|
||||||
throw new SuggestInputParseException(null, ALL_PATTERNS).prepend(input);
|
|
||||||
}
|
|
||||||
return new LinearBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
|
|
||||||
}
|
|
||||||
case "#l3d":
|
|
||||||
case "#linear3d": {
|
|
||||||
ArrayList<Pattern> patterns = new ArrayList<>();
|
|
||||||
for (String token : StringMan.split(rest, ',')) {
|
|
||||||
patterns.add(catchSuggestion(input, token, context));
|
|
||||||
}
|
|
||||||
if (patterns.isEmpty()) {
|
|
||||||
throw new SuggestInputParseException(null, ALL_PATTERNS).prepend(input);
|
|
||||||
}
|
|
||||||
return new Linear3DBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new SuggestInputParseException(input, DELEGATE_PATTERNS);
|
|
||||||
}
|
}
|
||||||
|
case "#id": {
|
||||||
|
return new IdPattern(Request.request().getEditSession(), catchSuggestion(input, rest, context));
|
||||||
|
}
|
||||||
|
case "#data": {
|
||||||
|
return new DataPattern(Request.request().getEditSession(), catchSuggestion(input, rest, context));
|
||||||
|
}
|
||||||
|
case "#biome": {
|
||||||
|
World world = context.requireWorld();
|
||||||
|
BiomeRegistry biomeRegistry = world.getWorldData().getBiomeRegistry();
|
||||||
|
List<BaseBiome> knownBiomes = biomeRegistry.getBiomes();
|
||||||
|
BaseBiome biome = Biomes.findBiomeByName(knownBiomes, rest, biomeRegistry);
|
||||||
|
return new BiomePattern(Request.request().getEditSession(), biome);
|
||||||
|
}
|
||||||
|
case "#~":
|
||||||
|
case "#r":
|
||||||
|
case "#relative":
|
||||||
|
case "#rel": {
|
||||||
|
return new RelativePattern(catchSuggestion(input, rest, context));
|
||||||
|
}
|
||||||
|
case "#!x":
|
||||||
|
case "#nx":
|
||||||
|
case "#nox": {
|
||||||
|
return new NoXPattern(catchSuggestion(input, rest, context));
|
||||||
|
}
|
||||||
|
case "#!y":
|
||||||
|
case "#ny":
|
||||||
|
case "#noy": {
|
||||||
|
return new NoYPattern(catchSuggestion(input, rest, context));
|
||||||
|
}
|
||||||
|
case "#!z":
|
||||||
|
case "#nz":
|
||||||
|
case "#noz": {
|
||||||
|
return new NoZPattern(catchSuggestion(input, rest, context));
|
||||||
|
}
|
||||||
|
case "#mask": {
|
||||||
|
List<String> split3 = suggestRemaining(rest, "#mask", "<mask>", "<pattern-if>", "<pattern-else>");
|
||||||
|
Pattern primary = catchSuggestion(input, split3.get(1), context);
|
||||||
|
Pattern secondary = catchSuggestion(input, split3.get(2), context);
|
||||||
|
PatternExtent extent = new PatternExtent(primary);
|
||||||
|
Request request = Request.request();
|
||||||
|
request.setExtent(extent);
|
||||||
|
request.setSession(context.getSession());
|
||||||
|
request.setWorld(context.getWorld());
|
||||||
|
context.setExtent(extent);
|
||||||
|
MaskFactory factory = worldEdit.getMaskFactory();
|
||||||
|
Mask mask = factory.parseFromInput(split3.get(0), context);
|
||||||
|
if (mask == null | primary == null || secondary == null) {
|
||||||
|
throw new SuggestInputParseException(null, "#mask:<mask>:<pattern-if>:<pattern-else>");
|
||||||
|
}
|
||||||
|
return new MaskedPattern(mask, extent, secondary);
|
||||||
|
}
|
||||||
|
case "#offset":
|
||||||
|
try {
|
||||||
|
List<String> split3 = suggestRemaining(rest, "#offset", "<dx>", "<dy>", "<dz>", "<pattern>");
|
||||||
|
int x = (int) Expression.compile(split3.get(0)).evaluate();
|
||||||
|
int y = (int) Expression.compile(split3.get(1)).evaluate();
|
||||||
|
int z = (int) Expression.compile(split3.get(2)).evaluate();
|
||||||
|
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
||||||
|
Pattern pattern = catchSuggestion(input, rest, context);
|
||||||
|
return new OffsetPattern(pattern, x, y, z);
|
||||||
|
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||||
|
throw new SuggestInputParseException(null, "#offset:<dx>:<dy>:<dz>:<pattern>");
|
||||||
|
}
|
||||||
|
case "#surfacespread": {
|
||||||
|
try {
|
||||||
|
List<String> split3 = suggestRemaining(rest, "#surfacespread", "<dx>", "<dy>", "<dz>", "<pattern>");
|
||||||
|
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
||||||
|
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
||||||
|
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
||||||
|
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
||||||
|
Pattern pattern = catchSuggestion(input, rest, context);
|
||||||
|
return new SurfaceRandomOffsetPattern(pattern, x, y, z);
|
||||||
|
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||||
|
throw new SuggestInputParseException(null, "#surfacespread:<dx>:<dy>:<dz>:<pattern>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "#solidspread": {
|
||||||
|
try {
|
||||||
|
List<String> split3 = suggestRemaining(rest, "#solidspread", "<dx>", "<dy>", "<dz>", "<pattern>");
|
||||||
|
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
||||||
|
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
||||||
|
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
||||||
|
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
||||||
|
Pattern pattern = catchSuggestion(input, rest, context);
|
||||||
|
return new SolidRandomOffsetPattern(pattern, x, y, z);
|
||||||
|
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||||
|
throw new SuggestInputParseException(null, "#solidspread:<dx>:<dy>:<dz>:<pattern>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "#randomoffset":
|
||||||
|
case "#spread": {
|
||||||
|
try {
|
||||||
|
List<String> split3 = suggestRemaining(rest, "#spread", "<dx>", "<dy>", "<dz>", "<pattern>");
|
||||||
|
int x = (int) Math.abs(Expression.compile(split3.get(0)).evaluate());
|
||||||
|
int y = (int) Math.abs(Expression.compile(split3.get(1)).evaluate());
|
||||||
|
int z = (int) Math.abs(Expression.compile(split3.get(2)).evaluate());
|
||||||
|
rest = StringMan.join(split3.subList(3, split3.size()), ":");
|
||||||
|
Pattern pattern = catchSuggestion(input, rest, context);
|
||||||
|
return new RandomOffsetPattern(pattern, x, y, z);
|
||||||
|
} catch (NumberFormatException | ExpressionException | IndexOutOfBoundsException e) {
|
||||||
|
throw new SuggestInputParseException(null, "#spread:<dx>:<dy>:<dz>:<pattern>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "#l":
|
||||||
|
case "#linear": {
|
||||||
|
ArrayList<Pattern> patterns = new ArrayList<>();
|
||||||
|
for (String token : StringMan.split(rest, ',')) {
|
||||||
|
patterns.add(catchSuggestion(input, token, context));
|
||||||
|
}
|
||||||
|
if (patterns.isEmpty()) {
|
||||||
|
throw new SuggestInputParseException(null, ALL_PATTERNS).prepend(input);
|
||||||
|
}
|
||||||
|
return new LinearBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
|
||||||
|
}
|
||||||
|
case "#l3d":
|
||||||
|
case "#linear3d": {
|
||||||
|
ArrayList<Pattern> patterns = new ArrayList<>();
|
||||||
|
for (String token : StringMan.split(rest, ',')) {
|
||||||
|
patterns.add(catchSuggestion(input, token, context));
|
||||||
|
}
|
||||||
|
if (patterns.isEmpty()) {
|
||||||
|
throw new SuggestInputParseException(null, ALL_PATTERNS).prepend(input);
|
||||||
|
}
|
||||||
|
return new Linear3DBlockPattern(patterns.toArray(new Pattern[patterns.size()]));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new SuggestInputParseException(input, MainUtil.joinArrayGeneric(SIMPLE_PATTERNS, DELEGATE_PATTERNS));
|
||||||
}
|
}
|
||||||
throw new SuggestInputParseException(input, MainUtil.joinArrayGeneric(SIMPLE_PATTERNS, DELEGATE_PATTERNS));
|
|
||||||
}
|
}
|
||||||
case '=': {
|
case '=': {
|
||||||
try {
|
try {
|
||||||
|
@ -246,7 +246,6 @@ public final class CommandManager {
|
|||||||
.registerMethods(new ToolCommands(worldEdit))
|
.registerMethods(new ToolCommands(worldEdit))
|
||||||
.registerMethods(new BrushCommands(worldEdit))
|
.registerMethods(new BrushCommands(worldEdit))
|
||||||
.parent().graph().getDispatcher();
|
.parent().graph().getDispatcher();
|
||||||
|
|
||||||
if (platform != null) {
|
if (platform != null) {
|
||||||
platform.registerCommands(dispatcher);
|
platform.registerCommands(dispatcher);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.extent.clipboard.io;
|
package com.sk89q.worldedit.extent.clipboard.io;
|
||||||
|
|
||||||
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.jnbt.NBTStreamer;
|
import com.boydti.fawe.jnbt.NBTStreamer;
|
||||||
import com.boydti.fawe.object.FaweOutputStream;
|
import com.boydti.fawe.object.FaweOutputStream;
|
||||||
@ -27,6 +28,8 @@ import com.boydti.fawe.object.clipboard.AbstractClipboardFormat;
|
|||||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||||
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
||||||
import com.boydti.fawe.object.clipboard.IClipboardFormat;
|
import com.boydti.fawe.object.clipboard.IClipboardFormat;
|
||||||
|
import com.boydti.fawe.object.clipboard.LazyClipboardHolder;
|
||||||
|
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||||
import com.boydti.fawe.object.io.PGZIPOutputStream;
|
import com.boydti.fawe.object.io.PGZIPOutputStream;
|
||||||
import com.boydti.fawe.object.io.ResettableFileInputStream;
|
import com.boydti.fawe.object.io.ResettableFileInputStream;
|
||||||
import com.boydti.fawe.object.schematic.FaweFormat;
|
import com.boydti.fawe.object.schematic.FaweFormat;
|
||||||
@ -35,29 +38,43 @@ import com.boydti.fawe.object.schematic.Schematic;
|
|||||||
import com.boydti.fawe.object.schematic.StructureFormat;
|
import com.boydti.fawe.object.schematic.StructureFormat;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.ReflectionUtils;
|
import com.boydti.fawe.util.ReflectionUtils;
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
import com.google.common.io.Files;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.sk89q.jnbt.NBTConstants;
|
import com.sk89q.jnbt.NBTConstants;
|
||||||
import com.sk89q.jnbt.NBTInputStream;
|
import com.sk89q.jnbt.NBTInputStream;
|
||||||
import com.sk89q.jnbt.NBTOutputStream;
|
import com.sk89q.jnbt.NBTOutputStream;
|
||||||
|
import com.sk89q.worldedit.LocalConfiguration;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
|
import com.sk89q.worldedit.world.registry.WorldData;
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
|
||||||
@ -297,6 +314,87 @@ public enum ClipboardFormat {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ClipboardHolder[] loadAllFromInput(Actor player, WorldData worldData, String input, boolean message) throws IOException {
|
||||||
|
checkNotNull(player);
|
||||||
|
checkNotNull(input);
|
||||||
|
WorldEdit worldEdit = WorldEdit.getInstance();
|
||||||
|
LocalConfiguration config = worldEdit.getConfiguration();
|
||||||
|
if (input.startsWith("http")) {
|
||||||
|
URL url = new URL(input);
|
||||||
|
URL webInterface = new URL(Settings.IMP.WEB.ASSETS);
|
||||||
|
if (!url.getHost().equalsIgnoreCase(webInterface.getHost())) {
|
||||||
|
if (message) BBC.WEB_UNAUTHORIZED.send(player, url);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ClipboardHolder[] clipboards = loadAllFromUrl(url, worldData);
|
||||||
|
return clipboards;
|
||||||
|
} else {
|
||||||
|
if (input.contains("../") && !player.hasPermission("worldedit.schematic.load.other")) {
|
||||||
|
if (message) BBC.NO_PERM.send(player, "worldedit.schematic.load.other");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
File working = worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||||
|
File dir = new File(working, (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? (player.getUniqueId().toString() + File.separator) : "") + input);
|
||||||
|
if (!dir.exists()) {
|
||||||
|
if ((!input.contains("/") && !input.contains("\\")) || player.hasPermission("worldedit.schematic.load.other")) {
|
||||||
|
dir = new File(worldEdit.getWorkingDirectoryFile(config.saveDir), input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!dir.exists() || !dir.isDirectory()) {
|
||||||
|
if (message) BBC.SCHEMATIC_NOT_FOUND.send(player, input);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ClipboardHolder[] clipboards = loadAllFromDirectory(dir, worldData);
|
||||||
|
if (clipboards.length < 1) {
|
||||||
|
if (message) BBC.SCHEMATIC_NOT_FOUND.send(player, input);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return clipboards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClipboardHolder[] loadAllFromDirectory(File dir, WorldData worldData) {
|
||||||
|
File[] files = dir.listFiles(new FileFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File pathname) {
|
||||||
|
return pathname.getName().endsWith(".schematic");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
LazyClipboardHolder[] clipboards = new LazyClipboardHolder[files.length];
|
||||||
|
for (int i = 0; i < files.length; i++) {
|
||||||
|
File file = files[i];
|
||||||
|
ByteSource source = Files.asByteSource(file);
|
||||||
|
clipboards[i] = new LazyClipboardHolder(source, this, worldData, null);
|
||||||
|
}
|
||||||
|
return clipboards;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClipboardHolder[] loadAllFromUrl(URL url, WorldData worldData) throws IOException {
|
||||||
|
List<LazyClipboardHolder> clipboards = new ArrayList<>();
|
||||||
|
try (ReadableByteChannel rbc = Channels.newChannel(url.openStream())) {
|
||||||
|
try (InputStream in = Channels.newInputStream(rbc)) {
|
||||||
|
try (ZipInputStream zip = new ZipInputStream(in)) {
|
||||||
|
ZipEntry entry;
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
while ((entry = zip.getNextEntry()) != null) {
|
||||||
|
if (entry.getName().endsWith(".schematic")) {
|
||||||
|
FastByteArrayOutputStream out = new FastByteArrayOutputStream();
|
||||||
|
int len = 0;
|
||||||
|
while ((len = zip.read(buffer)) > 0) {
|
||||||
|
out.write(buffer, 0, len);
|
||||||
|
}
|
||||||
|
byte[] array = out.toByteArray();
|
||||||
|
ByteSource source = ByteSource.wrap(array);
|
||||||
|
LazyClipboardHolder clipboard = new LazyClipboardHolder(source, this, worldData, null);
|
||||||
|
clipboards.add(clipboard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clipboards.toArray(new LazyClipboardHolder[clipboards.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
private void write(OutputStream value, Clipboard clipboard) {
|
private void write(OutputStream value, Clipboard clipboard) {
|
||||||
try {
|
try {
|
||||||
try (PGZIPOutputStream gzip = new PGZIPOutputStream(value)) {
|
try (PGZIPOutputStream gzip = new PGZIPOutputStream(value)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user