mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-25 03:55:35 +01:00
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 Method methodToNative;
|
||||
public static Method methodFromNative;
|
||||
private static boolean setupAdapter = false;
|
||||
|
||||
public BukkitQueue_0(final com.sk89q.worldedit.world.World world) {
|
||||
super(world);
|
||||
@ -137,6 +138,9 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
|
||||
public static void setupAdapter(BukkitImplAdapter adapter) {
|
||||
try {
|
||||
if (setupAdapter == (setupAdapter = true)) {
|
||||
return;
|
||||
}
|
||||
WorldEditPlugin instance = (WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit");
|
||||
Field fieldAdapter = WorldEditPlugin.class.getDeclaredField("bukkitAdapter");
|
||||
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.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;
|
||||
@ -20,8 +21,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
public class FullClipboardPattern extends AbstractPattern {
|
||||
private final Extent extent;
|
||||
private final Clipboard clipboard;
|
||||
private final BaseBlock block;
|
||||
|
||||
private final MutableBlockVector mutable = new MutableBlockVector();
|
||||
|
||||
/**
|
||||
@ -33,16 +32,19 @@ public class FullClipboardPattern extends AbstractPattern {
|
||||
checkNotNull(clipboard);
|
||||
this.clipboard = clipboard;
|
||||
this.extent = extent;
|
||||
Vector origin = clipboard.getOrigin();
|
||||
block = clipboard.getBlock(origin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock apply(Vector to) {
|
||||
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||
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));
|
||||
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;
|
||||
|
||||
import com.boydti.fawe.object.HasFaweQueue;
|
||||
import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
|
||||
import com.boydti.fawe.util.EditSessionBuilder;
|
||||
import com.boydti.fawe.util.MaskTraverser;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
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.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
||||
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.Mask;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
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.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@ -133,4 +143,77 @@ public class Schematic {
|
||||
editSession.flushQueue();
|
||||
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.ScrollTarget;
|
||||
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.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.CommandContext;
|
||||
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.util.command.binding.Switch;
|
||||
import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
@ -103,10 +97,6 @@ import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
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;
|
||||
@ -237,71 +227,11 @@ public class BrushCommands {
|
||||
}
|
||||
String filename = args.getString(1);
|
||||
try {
|
||||
WorldData worldData = player.getWorld().getWorldData();
|
||||
if (filename.startsWith("http")) {
|
||||
URL url = new URL(filename);
|
||||
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));
|
||||
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), filename, true);
|
||||
if (clipboards == null) {
|
||||
return;
|
||||
}
|
||||
tool.setScrollAction(new ScrollClipboard(tool, session, clipboards));
|
||||
break;
|
||||
} catch (IOException 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.object.FaweLimit;
|
||||
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.WorldCutClipboard;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
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.MaskTraverser;
|
||||
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.WorldEdit;
|
||||
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.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
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.mask.Mask;
|
||||
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.Operations;
|
||||
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.Selection;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.regions.RegionSelector;
|
||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||
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.parametric.Optional;
|
||||
import java.io.IOException;
|
||||
@ -373,7 +367,6 @@ public class ClipboardCommands {
|
||||
place(player, session, editSession, ignoreAirBlocks, atOrigin, selectPasted);
|
||||
return;
|
||||
}
|
||||
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
Region region = clipboard.getRegion();
|
||||
Vector to = atOrigin ? clipboard.getOrigin() : session.getPlacementPosition(player);
|
||||
@ -420,63 +413,13 @@ public class ClipboardCommands {
|
||||
@Switch('s') boolean selectPasted) throws WorldEditException {
|
||||
ClipboardHolder holder = session.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 to = atOrigin ? origin : session.getPlacementPosition(player);
|
||||
// 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) {
|
||||
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());
|
||||
}
|
||||
|
||||
Schematic schem = new Schematic(clipboard);
|
||||
schem.paste(editSession, to, !ignoreAirBlocks);
|
||||
|
||||
Region region = clipboard.getRegion().clone();
|
||||
if (selectPasted) {
|
||||
Vector max = to.add(region.getMaximumPoint().subtract(region.getMinimumPoint()));
|
||||
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.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.StringMan;
|
||||
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.ParserContext;
|
||||
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.pattern.BlockPattern;
|
||||
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.registry.BiomeRegistry;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -97,25 +117,13 @@ public class HashTagPatternParser extends FaweParser<Pattern> {
|
||||
}
|
||||
switch (input.toLowerCase().charAt(0)) {
|
||||
case '#': {
|
||||
switch (input) {
|
||||
String[] split2 = input.split(":");
|
||||
String rest = split2.length > 1 ? input.substring(split2[0].length() + 1) : "";
|
||||
switch (split2[0].toLowerCase()) {
|
||||
case "#*":
|
||||
case "#existing": {
|
||||
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 "#copy": {
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
String[] split2 = input.split(":");
|
||||
if (split2.length > 1 || input.endsWith(":")) {
|
||||
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":
|
||||
case "#fullcopy": {
|
||||
LocalSession session = context.requireSession();
|
||||
if (session != null) {
|
||||
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>");
|
||||
if (split2.length > 1) {
|
||||
String location = split2[1];
|
||||
try {
|
||||
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(context.getActor(), context.requireWorld().getWorldData(), location, true);
|
||||
if (clipboards == null) {
|
||||
System.out.println("NULL!");
|
||||
throw new InputParseException("#fullcopy:<source>");
|
||||
}
|
||||
boolean random = split2.length == 3 && split2[2].equalsIgnoreCase("true");
|
||||
return new RandomFullClipboardPattern(Request.request().getEditSession(), context.requireWorld().getWorldData(), clipboards, random);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
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 "#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 '=': {
|
||||
try {
|
||||
|
@ -246,7 +246,6 @@ public final class CommandManager {
|
||||
.registerMethods(new ToolCommands(worldEdit))
|
||||
.registerMethods(new BrushCommands(worldEdit))
|
||||
.parent().graph().getDispatcher();
|
||||
|
||||
if (platform != null) {
|
||||
platform.registerCommands(dispatcher);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.jnbt.NBTStreamer;
|
||||
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.FaweClipboard;
|
||||
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.ResettableFileInputStream;
|
||||
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.util.MainUtil;
|
||||
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.sk89q.jnbt.NBTConstants;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
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.Clipboard;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
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.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
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) {
|
||||
try {
|
||||
try (PGZIPOutputStream gzip = new PGZIPOutputStream(value)) {
|
||||
|
Loading…
Reference in New Issue
Block a user