Various minor
re-implement forge/sponge modules Fix NBT copy error Fix entity/tile error Some work on multi-clipboards
This commit is contained in:
parent
7a4b7be26a
commit
b020e3ebe6
@ -54,7 +54,7 @@ public class BukkitImageListener implements Listener {
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onPlayerInteractEntity(AsyncPlayerChatEvent event) {
|
||||
Set<Player> recipients = event.getRecipients();
|
||||
Iterator<Player> iter = recipients.iterator();
|
||||
|
@ -21,8 +21,12 @@ import com.boydti.fawe.util.chat.ChatManager;
|
||||
import com.boydti.fawe.util.chat.PlainChatManager;
|
||||
import com.boydti.fawe.util.cui.CUI;
|
||||
import com.boydti.fawe.util.metrics.BStats;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.CompoundTagBuilder;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.BlockWorldVector;
|
||||
import com.sk89q.worldedit.CuboidClipboard;
|
||||
@ -118,6 +122,8 @@ import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.ExpressionEnvironment;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.For;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.Functions;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.SimpleFor;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.While;
|
||||
import com.sk89q.worldedit.math.convolution.HeightMap;
|
||||
import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
@ -647,6 +653,8 @@ public class Fawe {
|
||||
Expression.inject(); // Optimizations
|
||||
Functions.inject(); // Optimizations
|
||||
For.inject(); // Fixes
|
||||
SimpleFor.inject(); // Fixes
|
||||
While.inject(); // Fixes
|
||||
// BlockData
|
||||
BlockData.inject(); // Temporary fix for 1.9.4
|
||||
BundledBlockData.inject(); // Add custom rotation
|
||||
@ -663,6 +671,10 @@ public class Fawe {
|
||||
// NBT
|
||||
NBTInputStream.inject(); // Add actual streaming + Optimizations + New methods
|
||||
NBTOutputStream.inject(); // New methods
|
||||
Tag.inject(); // Expose raw data
|
||||
CompoundTag.inject(); // Expose raw data
|
||||
CompoundTagBuilder.inject(); // make accessible
|
||||
ListTag.inject(); // Expose raw data
|
||||
// Math
|
||||
KochanekBartelsInterpolation.inject(); // Optimizations
|
||||
AffineTransform.inject(); // Optimizations
|
||||
|
@ -7,6 +7,7 @@ import com.boydti.fawe.config.Commands;
|
||||
import com.boydti.fawe.jnbt.anvil.HeightMapMCAGenerator;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
|
||||
import com.boydti.fawe.util.CleanTextureUtil;
|
||||
import com.boydti.fawe.util.FilteredTextureUtil;
|
||||
import com.boydti.fawe.util.ImgurUtility;
|
||||
@ -452,14 +453,14 @@ public class CFICommands extends MethodCommands {
|
||||
|
||||
World world = fp.getWorld();
|
||||
WorldData wd = world.getWorldData();
|
||||
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(fp.getPlayer(), wd, schematic, true);
|
||||
if (clipboards == null) {
|
||||
MultiClipboardHolder multi = ClipboardFormat.SCHEMATIC.loadAllFromInput(fp.getPlayer(), wd, schematic, true);
|
||||
if (multi == null) {
|
||||
return;
|
||||
}
|
||||
if (imageMask == null) {
|
||||
gen.addSchems(mask, wd, clipboards, rarity, distance, rotate);
|
||||
gen.addSchems(mask, wd, multi.getHolders(), rarity, distance, rotate);
|
||||
} else {
|
||||
gen.addSchems(imageMask, mask, wd, clipboards, rarity, distance, rotate);
|
||||
gen.addSchems(imageMask, mask, wd, multi.getHolders(), rarity, distance, rotate);
|
||||
}
|
||||
msg("Added schematics!").send(fp);
|
||||
populate(fp);
|
||||
|
@ -194,6 +194,7 @@ public enum BBC {
|
||||
SCHEMATIC_LIST("Available files (Filename: Format) [%s0/%s1]:", "Worldedit.Schematic"),
|
||||
SCHEMATIC_LIST_ELEM("&8 - &a%s0 &8- &7%s1", "Worldedit.Schematic"),
|
||||
|
||||
CLIPBOARD_URI_NOT_FOUND("You do not have %s0 loaded", "WorldEdit.Clipboard"),
|
||||
CLIPBOARD_CLEARED("Clipboard cleared", "WorldEdit.Clipboard"),
|
||||
CLIPBOARD_INVALID_FORMAT("Unknown clipboard format: %s0", "WorldEdit.Clipboard"),
|
||||
|
||||
|
@ -34,6 +34,7 @@ import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
private final MutableBlockVector mutable = new MutableBlockVector();
|
||||
@ -238,13 +239,13 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void addSchems(Mask mask, WorldData worldData, ClipboardHolder[] clipboards, int rarity, boolean rotate) throws WorldEditException {
|
||||
public void addSchems(Mask mask, WorldData worldData, List<ClipboardHolder> clipboards, int rarity, boolean rotate) throws WorldEditException {
|
||||
CuboidRegion region = new CuboidRegion(new Vector(0, 0, 0), new Vector(getWidth(), 255, getLength()));
|
||||
addSchems(region, mask, worldData, clipboards, rarity, rotate);
|
||||
update();
|
||||
}
|
||||
|
||||
public void addSchems(BufferedImage img, Mask mask, WorldData worldData, ClipboardHolder[] clipboards, int rarity, int distance, boolean randomRotate) throws WorldEditException {
|
||||
public void addSchems(BufferedImage img, Mask mask, WorldData worldData, List<ClipboardHolder> clipboards, int rarity, int distance, boolean randomRotate) throws WorldEditException {
|
||||
if (img.getWidth() != getWidth() || img.getHeight() != getLength())
|
||||
throw new IllegalArgumentException("Input image dimensions do not match the current height map!");
|
||||
double doubleRarity = rarity / 100d;
|
||||
@ -268,7 +269,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
continue;
|
||||
}
|
||||
placed.add(x, z);
|
||||
ClipboardHolder holder = clipboards[PseudoRandom.random.random(clipboards.length)];
|
||||
ClipboardHolder holder = clipboards.get(PseudoRandom.random.random(clipboards.size()));
|
||||
if (randomRotate) {
|
||||
int rotate = PseudoRandom.random.random(4) * 90;
|
||||
if (rotate != 0) {
|
||||
@ -296,7 +297,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
update();
|
||||
}
|
||||
|
||||
public void addSchems(Mask mask, WorldData worldData, ClipboardHolder[] clipboards, int rarity, int distance, boolean randomRotate) throws WorldEditException {
|
||||
public void addSchems(Mask mask, WorldData worldData, List<ClipboardHolder> clipboards, int rarity, int distance, boolean randomRotate) throws WorldEditException {
|
||||
int scaledRarity = (256 * rarity) / 100;
|
||||
int index = 0;
|
||||
AffineTransform identity = new AffineTransform();
|
||||
@ -318,7 +319,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements Extent {
|
||||
}
|
||||
mutable.mutY(y + 1);
|
||||
placed.add(x, z);
|
||||
ClipboardHolder holder = clipboards[PseudoRandom.random.random(clipboards.length)];
|
||||
ClipboardHolder holder = clipboards.get(PseudoRandom.random.random(clipboards.size()));
|
||||
if (randomRotate) {
|
||||
int rotate = PseudoRandom.random.random(4) * 90;
|
||||
if (rotate != 0) {
|
||||
|
@ -11,18 +11,19 @@ import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
import java.util.List;
|
||||
|
||||
public class SchemGen extends Resource {
|
||||
|
||||
private final Extent extent;
|
||||
private final WorldData worldData;
|
||||
private final ClipboardHolder[] clipboards;
|
||||
private final List<ClipboardHolder> clipboards;
|
||||
private final boolean randomRotate;
|
||||
private final Mask mask;
|
||||
|
||||
private MutableBlockVector mutable = new MutableBlockVector();
|
||||
|
||||
public SchemGen(Mask mask, Extent extent, WorldData worldData, ClipboardHolder[] clipboards, boolean randomRotate) {
|
||||
public SchemGen(Mask mask, Extent extent, WorldData worldData, List<ClipboardHolder> clipboards, boolean randomRotate) {
|
||||
this.mask = mask;
|
||||
this.extent = extent;
|
||||
this.worldData = worldData;
|
||||
@ -41,7 +42,7 @@ public class SchemGen extends Resource {
|
||||
return false;
|
||||
}
|
||||
mutable.mutY(y + 1);
|
||||
ClipboardHolder holder = clipboards[PseudoRandom.random.random(clipboards.length)];
|
||||
ClipboardHolder holder = clipboards.get(PseudoRandom.random.random(clipboards.size()));
|
||||
if (randomRotate) {
|
||||
holder.setTransform(new AffineTransform().rotateY(PseudoRandom.random.random(4) * 90));
|
||||
}
|
||||
|
@ -11,14 +11,15 @@ import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import java.util.List;
|
||||
|
||||
public class PopulateSchem implements Brush {
|
||||
private final Mask mask;
|
||||
private final boolean randomRotate;
|
||||
private final ClipboardHolder[] clipboards;
|
||||
private final List<ClipboardHolder> clipboards;
|
||||
private final int rarity;
|
||||
|
||||
public PopulateSchem(Mask mask, ClipboardHolder[] clipboards, int rarity, boolean randomRotate) {
|
||||
public PopulateSchem(Mask mask, List<ClipboardHolder> clipboards, int rarity, boolean randomRotate) {
|
||||
this.mask = mask;
|
||||
this.clipboards = clipboards;
|
||||
this.rarity = rarity;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.boydti.fawe.object.brush.scroll;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
@ -11,7 +12,6 @@ import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class ScrollAction implements ScrollTool {
|
||||
@ -34,11 +34,11 @@ public abstract class ScrollAction implements ScrollTool {
|
||||
}
|
||||
String filename = split[1];
|
||||
try {
|
||||
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), filename, message);
|
||||
if (clipboards == null) {
|
||||
MultiClipboardHolder multi = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), filename, message);
|
||||
if (multi == null) {
|
||||
return null;
|
||||
}
|
||||
return (new ScrollClipboard(tool, session, clipboards));
|
||||
return (new ScrollClipboard(tool, session, multi.getHolders()));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -5,13 +5,14 @@ import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import java.util.List;
|
||||
|
||||
public class ScrollClipboard extends ScrollAction {
|
||||
private final ClipboardHolder[] clipboards;
|
||||
private final List<ClipboardHolder> clipboards;
|
||||
private final LocalSession session;
|
||||
int index = 0;
|
||||
|
||||
public ScrollClipboard(BrushTool tool, LocalSession session, ClipboardHolder[] clipboards) {
|
||||
public ScrollClipboard(BrushTool tool, LocalSession session, List<ClipboardHolder> clipboards) {
|
||||
super(tool);
|
||||
this.clipboards = clipboards;
|
||||
this.session = session;
|
||||
@ -19,8 +20,8 @@ public class ScrollClipboard extends ScrollAction {
|
||||
|
||||
@Override
|
||||
public boolean increment(Player player, int amount) {
|
||||
index = MathMan.wrap(index + amount, 0, clipboards.length - 1);
|
||||
ClipboardHolder clipboard = clipboards[index];
|
||||
index = MathMan.wrap(index + amount, 0, clipboards.size() - 1);
|
||||
ClipboardHolder clipboard = clipboards.get(index);
|
||||
session.setClipboard(clipboard);
|
||||
return true;
|
||||
}
|
||||
|
@ -88,6 +88,10 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
private void init() throws IOException {
|
||||
if (this.fc == null) {
|
||||
this.fc = braf.getChannel();
|
||||
@ -280,6 +284,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
MainUtil.stacktrace();
|
||||
try {
|
||||
if (mbb != null) {
|
||||
mbb.force();
|
||||
|
@ -13,7 +13,7 @@ import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@ -26,17 +26,17 @@ public class EmptyClipboard implements Clipboard {
|
||||
|
||||
@Override
|
||||
public Region getRegion() {
|
||||
return new CuboidRegion(new Vector(), new Vector());
|
||||
return new CuboidRegion(Vector.ZERO, Vector.ZERO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector getDimensions() {
|
||||
return new Vector();
|
||||
return Vector.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector getOrigin() {
|
||||
return new Vector();
|
||||
return Vector.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -45,22 +45,22 @@ public class EmptyClipboard implements Clipboard {
|
||||
|
||||
@Override
|
||||
public Vector getMinimumPoint() {
|
||||
return new Vector();
|
||||
return Vector.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector getMaximumPoint() {
|
||||
return new Vector();
|
||||
return Vector.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Entity> getEntities(Region region) {
|
||||
return new ArrayList<>();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Entity> getEntities() {
|
||||
return new ArrayList<>();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -2,16 +2,17 @@ package com.boydti.fawe.object.clipboard;
|
||||
|
||||
import com.boydti.fawe.object.schematic.StructureFormat;
|
||||
import com.google.common.io.ByteSource;
|
||||
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.ClipboardReader;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.SchematicReader;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.UUID;
|
||||
|
||||
public class LazyClipboardHolder extends ClipboardHolder {
|
||||
public class LazyClipboardHolder extends URIClipboardHolder {
|
||||
private final ByteSource source;
|
||||
private final ClipboardFormat format;
|
||||
private final UUID uuid;
|
||||
@ -22,16 +23,20 @@ public class LazyClipboardHolder extends ClipboardHolder {
|
||||
*
|
||||
* @param worldData the mapping of blocks, entities, and so on
|
||||
*/
|
||||
public LazyClipboardHolder(ByteSource source, ClipboardFormat format, WorldData worldData, UUID uuid) {
|
||||
super(EmptyClipboard.INSTANCE, worldData);
|
||||
public LazyClipboardHolder(URI uri, ByteSource source, ClipboardFormat format, WorldData worldData, UUID uuid) {
|
||||
super(uri, EmptyClipboard.INSTANCE, worldData);
|
||||
this.source = source;
|
||||
this.format = format;
|
||||
this.uuid = uuid != null ? uuid : UUID.randomUUID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Clipboard clipboard) {
|
||||
return this.clipboard == clipboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clipboard getClipboard() {
|
||||
public synchronized Clipboard getClipboard() {
|
||||
if (clipboard == null) {
|
||||
try {
|
||||
try (InputStream in = source.openBufferedStream()) {
|
||||
@ -51,4 +56,12 @@ public class LazyClipboardHolder extends ClipboardHolder {
|
||||
}
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
if (clipboard instanceof BlockArrayClipboard) {
|
||||
((BlockArrayClipboard) clipboard).close();
|
||||
}
|
||||
clipboard = null;
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +1,149 @@
|
||||
package com.boydti.fawe.object.clipboard;
|
||||
|
||||
import com.boydti.fawe.object.PseudoRandom;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MultiClipboardHolder extends ClipboardHolder {
|
||||
private final ClipboardHolder[] holders;
|
||||
|
||||
private ClipboardHolder holder;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public MultiClipboardHolder(WorldData worldData, ClipboardHolder... holders) {
|
||||
super(holders[0].getClipboard(), worldData);
|
||||
holder = holders[0];
|
||||
this.holders = holders;
|
||||
public class MultiClipboardHolder extends URIClipboardHolder {
|
||||
private final List<URIClipboardHolder> holders;
|
||||
private Clipboard[] cached;
|
||||
|
||||
public MultiClipboardHolder(WorldData worldData) {
|
||||
this(URI.create(""), worldData);
|
||||
}
|
||||
|
||||
public MultiClipboardHolder(URI uri, WorldData worldData) {
|
||||
super(uri, EmptyClipboard.INSTANCE, worldData);
|
||||
holders = new ArrayList<>();
|
||||
}
|
||||
|
||||
public MultiClipboardHolder(URI uri, WorldData worldData, URIClipboardHolder... addHolders) {
|
||||
this(uri, worldData);
|
||||
for (URIClipboardHolder h : addHolders) add(h);
|
||||
}
|
||||
|
||||
public MultiClipboardHolder(Clipboard clipboard, WorldData worldData) {
|
||||
super(URI.create(""), EmptyClipboard.INSTANCE, worldData);
|
||||
holders = new ArrayList<>();
|
||||
URI uri = URI.create("");
|
||||
if (clipboard instanceof BlockArrayClipboard) {
|
||||
FaweClipboard fc = ((BlockArrayClipboard) clipboard).IMP;
|
||||
if (fc instanceof DiskOptimizedClipboard) {
|
||||
uri = ((DiskOptimizedClipboard) fc).getFile().toURI();
|
||||
}
|
||||
}
|
||||
add(uri, clipboard);
|
||||
}
|
||||
|
||||
public void remove(URI uri) {
|
||||
cached = null;
|
||||
if (getUri().equals(uri)) {
|
||||
for (ClipboardHolder holder : holders) holder.close();
|
||||
holders.clear();
|
||||
return;
|
||||
}
|
||||
for (int i = holders.size() - 1; i >= 0; i--) {
|
||||
URIClipboardHolder holder = holders.get(i);
|
||||
if (holder.contains(uri)) {
|
||||
if (holder instanceof MultiClipboardHolder) {
|
||||
((MultiClipboardHolder) holder).remove(uri);
|
||||
} else {
|
||||
holders.remove(i).close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void add(URIClipboardHolder holder) {
|
||||
add((ClipboardHolder) holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Clipboard clipboard) {
|
||||
for (ClipboardHolder holder : holders) {
|
||||
if (holder.contains(clipboard)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void add(ClipboardHolder holder) {
|
||||
checkNotNull(holder);
|
||||
if (holder instanceof URIClipboardHolder) {
|
||||
holders.add((URIClipboardHolder) holder);
|
||||
} else {
|
||||
URI uri = URI.create(UUID.randomUUID().toString());
|
||||
if (!contains(uri)) {
|
||||
holders.add(new URIClipboardHolder(uri, holder.getClipboard(), holder.getWorldData()));
|
||||
}
|
||||
}
|
||||
cached = null;
|
||||
}
|
||||
|
||||
public void add(URI uri, Clipboard clip) {
|
||||
checkNotNull(clip);
|
||||
checkNotNull(uri);
|
||||
add(new URIClipboardHolder(uri, clip, getWorldData()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Clipboard> getClipboards() {
|
||||
ArrayList<Clipboard> all = new ArrayList<>();
|
||||
for (ClipboardHolder holder : holders) {
|
||||
all.addAll(holder.getClipboards());
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClipboardHolder> getHolders() {
|
||||
ArrayList<ClipboardHolder> holders = new ArrayList<>();
|
||||
for (ClipboardHolder holder : holders) {
|
||||
holders.addAll(holder.getHolders());
|
||||
}
|
||||
return holders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(URI uri) {
|
||||
if (getUri().equals(uri)) {
|
||||
return true;
|
||||
}
|
||||
for (URIClipboardHolder uch : holders) {
|
||||
if (uch.contains(uri)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clipboard getClipboard() {
|
||||
holder = holders[PseudoRandom.random.nextInt(holders.length)];
|
||||
return holder.getClipboard();
|
||||
Clipboard[] available = cached;
|
||||
if (available == null) {
|
||||
cached = available = getClipboards().toArray(new Clipboard[0]);
|
||||
}
|
||||
switch (available.length) {
|
||||
case 0: return EmptyClipboard.INSTANCE;
|
||||
case 1: return available[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transform getTransform() {
|
||||
return holder.getTransform();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransform(Transform transform) {
|
||||
holder.setTransform(transform);
|
||||
int index = PseudoRandom.random.nextInt(available.length);
|
||||
return available[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
cached = null;
|
||||
for (ClipboardHolder holder : holders) {
|
||||
if (holder != null) holder.close();
|
||||
holder.close();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.boydti.fawe.object.clipboard;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
import java.net.URI;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class URIClipboardHolder extends ClipboardHolder {
|
||||
private final URI uri;
|
||||
|
||||
public URIClipboardHolder(URI uri, Clipboard clipboard, WorldData worldData) {
|
||||
super(clipboard, worldData);
|
||||
checkNotNull(uri);
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public boolean contains(URI uri) {
|
||||
checkNotNull(uri);
|
||||
return this.uri.equals(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated If a holder has multiple sources, this will return an empty URI
|
||||
* @return The original source of this clipboard (usually a file or url)
|
||||
*/
|
||||
@Deprecated
|
||||
public URI getUri() {
|
||||
return uri;
|
||||
}
|
||||
}
|
@ -15,19 +15,20 @@ import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
import java.io.IOException;
|
||||
import java.io.NotSerializableException;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
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 final List<ClipboardHolder> clipboards;
|
||||
private boolean randomRotate;
|
||||
private boolean randomFlip;
|
||||
private WorldData worldData;
|
||||
|
||||
public RandomFullClipboardPattern(Extent extent, WorldData worldData, ClipboardHolder[] clipboards, boolean randomRotate, boolean randomFlip) {
|
||||
public RandomFullClipboardPattern(Extent extent, WorldData worldData, List<ClipboardHolder> clipboards, boolean randomRotate, boolean randomFlip) {
|
||||
checkNotNull(clipboards);
|
||||
this.clipboards = clipboards;
|
||||
this.extent = extent;
|
||||
@ -37,7 +38,7 @@ public class RandomFullClipboardPattern extends AbstractPattern {
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector setPosition, Vector getPosition) throws WorldEditException {
|
||||
ClipboardHolder holder = clipboards[PseudoRandom.random.random(clipboards.length)];
|
||||
ClipboardHolder holder = clipboards.get(PseudoRandom.random.random(clipboards.size()));
|
||||
AffineTransform transform = new AffineTransform();
|
||||
if (randomRotate) {
|
||||
transform = transform.rotateY(PseudoRandom.random.random(4) * 90);
|
||||
|
@ -67,6 +67,10 @@ public class ReflectionUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T as(Class<T> t, Object o) {
|
||||
return t.isInstance(o) ? t.cast(o) : null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Enum<?>> T addEnum(Class<T> enumType, String enumName) {
|
||||
|
||||
@ -186,6 +190,7 @@ public class ReflectionUtils {
|
||||
public static <T> List<T> getList(List<T> list) {
|
||||
try {
|
||||
Class<? extends List> clazz = (Class<? extends List>) Class.forName("java.util.Collections$UnmodifiableList");
|
||||
if (!clazz.isInstance(list)) return list;
|
||||
Field m = clazz.getDeclaredField("list");
|
||||
m.setAccessible(true);
|
||||
return (List<T>) m.get(list);
|
||||
|
@ -47,6 +47,10 @@ public class Message {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean supportsInteraction() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public Message text(BBC caption, Object... args) {
|
||||
return text(caption.format(args));
|
||||
}
|
||||
|
@ -80,8 +80,8 @@ public class ImageUtil {
|
||||
throw new IOException("Failed to read " + url + ", please try again later");
|
||||
}
|
||||
return img;
|
||||
} else if (arg.startsWith("file://")) {
|
||||
arg = arg.substring(7);
|
||||
} else if (arg.startsWith("file:/")) {
|
||||
arg = arg.replaceFirst("file:/+", "");
|
||||
File file = MainUtil.getFile(MainUtil.getFile(Fawe.imp().getDirectory(), com.boydti.fawe.config.Settings.IMP.PATHS.HEIGHTMAP), arg);
|
||||
return MainUtil.readImage(file);
|
||||
} else {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.sk89q.jnbt;
|
||||
|
||||
import com.sk89q.worldedit.function.entity.ExtentEntityCopy;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -406,4 +407,7 @@ public final class CompoundTag extends Tag {
|
||||
return bldr.toString();
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return CompoundTag.class;
|
||||
}
|
||||
}
|
@ -201,4 +201,7 @@ public class CompoundTagBuilder {
|
||||
return new CompoundTagBuilder();
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return CompoundTagBuilder.class;
|
||||
}
|
||||
}
|
@ -419,4 +419,8 @@ public final class ListTag<T extends Tag> extends Tag {
|
||||
return bldr.toString();
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return ListTag.class;
|
||||
}
|
||||
|
||||
}
|
@ -5,9 +5,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
/**
|
||||
* Some data with a name
|
||||
*/
|
||||
public class NamedData {
|
||||
public class NamedData<T> {
|
||||
private final String name;
|
||||
private final Object data;
|
||||
private final T data;
|
||||
|
||||
/**
|
||||
* Create a new named tag.
|
||||
@ -15,7 +15,7 @@ public class NamedData {
|
||||
* @param name the name
|
||||
* @param data the data
|
||||
*/
|
||||
public NamedData(String name, Object data) {
|
||||
public NamedData(String name, T data) {
|
||||
checkNotNull(name);
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
@ -35,7 +35,7 @@ public class NamedData {
|
||||
*
|
||||
* @return the tag
|
||||
*/
|
||||
public Object getValue() {
|
||||
public T getValue() {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@ -35,4 +35,7 @@ public abstract class Tag {
|
||||
return getValue();
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return Tag.class;
|
||||
}
|
||||
}
|
@ -789,9 +789,13 @@ public class LocalSession {
|
||||
* @param clipboard the clipboard, or null if the clipboard is to be cleared
|
||||
*/
|
||||
public void setClipboard(@Nullable ClipboardHolder clipboard) {
|
||||
if (this.clipboard == clipboard) return;
|
||||
|
||||
if (this.clipboard != null) {
|
||||
if (clipboard == null || !clipboard.contains(this.clipboard.getClipboard())) {
|
||||
this.clipboard.close();
|
||||
}
|
||||
}
|
||||
this.clipboard = clipboard;
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@ import com.boydti.fawe.object.brush.SurfaceSphereBrush;
|
||||
import com.boydti.fawe.object.brush.SurfaceSpline;
|
||||
import com.boydti.fawe.object.brush.heightmap.ScalableHeightMap;
|
||||
import com.boydti.fawe.object.brush.sweep.SweepBrush;
|
||||
import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
|
||||
import com.boydti.fawe.object.mask.IdMask;
|
||||
import com.boydti.fawe.util.ColorUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
@ -471,12 +472,12 @@ public class BrushCommands extends MethodCommands {
|
||||
|
||||
|
||||
try {
|
||||
ClipboardHolder[] clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), clipboard, true);
|
||||
MultiClipboardHolder clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), clipboard, true);
|
||||
if (clipboards == null) {
|
||||
return null;
|
||||
}
|
||||
return get(context)
|
||||
.setBrush(new PopulateSchem(mask, clipboards, (int) density, rotate))
|
||||
.setBrush(new PopulateSchem(mask, clipboards.getHolders(), (int) density, rotate))
|
||||
.setSize(radius);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
@ -437,7 +437,10 @@ public class ClipboardCommands extends MethodCommands {
|
||||
@Switch('a') final boolean ignoreAirBlocks, @Switch('o') boolean atOrigin,
|
||||
@Switch('s') boolean selectPasted) throws WorldEditException {
|
||||
ClipboardHolder holder = session.getClipboard();
|
||||
System.out.println(holder);
|
||||
final Clipboard clipboard = holder.getClipboard();
|
||||
System.out.println(clipboard.getDimensions());
|
||||
System.out.println(clipboard.getClass());
|
||||
final Vector origin = clipboard.getOrigin();
|
||||
final Vector to = atOrigin ? origin : session.getPlacementPosition(player);
|
||||
|
||||
@ -500,6 +503,7 @@ public class ClipboardCommands extends MethodCommands {
|
||||
BBC.COMMAND_FLIPPED.send(player);
|
||||
}
|
||||
|
||||
@Deprecated // See SchematicCommands#clear
|
||||
@Command(
|
||||
aliases = {"clearclipboard"},
|
||||
usage = "",
|
||||
|
@ -3,6 +3,7 @@ package com.sk89q.worldedit.command;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.object.DataAnglePattern;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
|
||||
import com.boydti.fawe.object.collection.RandomCollection;
|
||||
import com.boydti.fawe.object.pattern.AngleColorPattern;
|
||||
import com.boydti.fawe.object.pattern.AverageColorPattern;
|
||||
@ -59,6 +60,8 @@ import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.awt.Color;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Command(aliases = {"patterns"},
|
||||
@ -209,7 +212,7 @@ public class PatternCommands extends MethodCommands {
|
||||
max = 2
|
||||
)
|
||||
public Pattern fullcopy(Player player, Extent extent, LocalSession session, @Optional("#copy") String location, @Optional("false") boolean rotate, @Optional("false") boolean flip) throws EmptyClipboardException, InputParseException, IOException {
|
||||
ClipboardHolder[] clipboards;
|
||||
List<ClipboardHolder> clipboards;
|
||||
switch (location.toLowerCase()) {
|
||||
case "#copy":
|
||||
case "#clipboard":
|
||||
@ -220,10 +223,11 @@ public class PatternCommands extends MethodCommands {
|
||||
if (!rotate && !flip) {
|
||||
return new FullClipboardPattern(extent, clipboard.getClipboard());
|
||||
}
|
||||
clipboards = new ClipboardHolder[]{clipboard};
|
||||
clipboards = Collections.singletonList(clipboard);
|
||||
break;
|
||||
default:
|
||||
clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), location, true);
|
||||
MultiClipboardHolder multi = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, player.getWorld().getWorldData(), location, true);
|
||||
clipboards = multi != null ? multi.getHolders() : null;
|
||||
break;
|
||||
}
|
||||
if (clipboards == null) {
|
||||
|
@ -23,8 +23,11 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Commands;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.clipboard.remap.ClipboardRemapper;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.RunnableVal3;
|
||||
import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
|
||||
import com.boydti.fawe.object.clipboard.URIClipboardHolder;
|
||||
import com.boydti.fawe.object.clipboard.remap.ClipboardRemapper;
|
||||
import com.boydti.fawe.object.schematic.StructureFormat;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.chat.Message;
|
||||
@ -56,6 +59,8 @@ import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
@ -65,10 +70,13 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
import static com.boydti.fawe.util.ReflectionUtils.as;
|
||||
|
||||
/**
|
||||
* Commands that work with schematic files.
|
||||
*/
|
||||
@Command(aliases = {"schematic", "schem", "/schematic", "/schem"}, desc = "Commands that work with schematic files")
|
||||
@Command(aliases = {"schematic", "schem", "/schematic", "/schem", "clipboard", "/clipboard"}, desc = "Commands that work with schematic files")
|
||||
public class SchematicCommands extends MethodCommands {
|
||||
|
||||
private static final Logger log = Logger.getLogger(SchematicCommands.class.getCanonicalName());
|
||||
@ -99,10 +107,22 @@ public class SchematicCommands extends MethodCommands {
|
||||
}
|
||||
try {
|
||||
WorldData wd = player.getWorld().getWorldData();
|
||||
session.setClipboard(null);
|
||||
ClipboardHolder[] all = format.loadAllFromInput(player, wd, filename, true);
|
||||
|
||||
MultiClipboardHolder all = format.loadAllFromInput(player, wd, filename, true);
|
||||
if (all != null) {
|
||||
MultiClipboardHolder multi = new MultiClipboardHolder(wd, all);
|
||||
ClipboardHolder existing = session.getExistingClipboard();
|
||||
MultiClipboardHolder multi;
|
||||
if (existing instanceof MultiClipboardHolder) {
|
||||
multi = (MultiClipboardHolder) existing;
|
||||
for (ClipboardHolder holder : all.getHolders()) {
|
||||
multi.add(holder);
|
||||
}
|
||||
} else {
|
||||
multi = all;
|
||||
if (existing != null) {
|
||||
multi.add(existing);
|
||||
}
|
||||
}
|
||||
session.setClipboard(multi);
|
||||
BBC.SCHEMATIC_LOADED.send(player, filename);
|
||||
}
|
||||
@ -111,6 +131,57 @@ public class SchematicCommands extends MethodCommands {
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"clear"},
|
||||
usage = "",
|
||||
desc = "Clear your clipboard",
|
||||
min = 0,
|
||||
max = 0
|
||||
)
|
||||
@CommandPermissions({"worldedit.clipboard.clear", "worldedit.schematic.clear"})
|
||||
public void clear(Player player, LocalSession session) throws WorldEditException {
|
||||
session.setClipboard(null);
|
||||
BBC.CLIPBOARD_CLEARED.send(player);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"unload"},
|
||||
usage = "[file]",
|
||||
desc = "Remove a clipboard from your multi-clipboard",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
@CommandPermissions({"worldedit.clipboard.clear", "worldedit.schematic.clear"})
|
||||
public void unload(Player player, LocalSession session, String fileName) throws WorldEditException {
|
||||
URI uri;
|
||||
if (fileName.startsWith("file:/") || fileName.startsWith("http://") || fileName.startsWith("https://")) {
|
||||
uri = URI.create(fileName);
|
||||
} else {
|
||||
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
||||
File working = this.worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||
File root = Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? new File(working, player.getUniqueId().toString()) : working;
|
||||
uri = new File(root, fileName).toURI();
|
||||
}
|
||||
|
||||
boolean removed = false;
|
||||
ClipboardHolder clipboard = session.getClipboard();
|
||||
if (clipboard instanceof URIClipboardHolder) {
|
||||
URIClipboardHolder identifiable = (URIClipboardHolder) clipboard;
|
||||
if (identifiable.contains(uri)) {
|
||||
if (identifiable instanceof MultiClipboardHolder) {
|
||||
MultiClipboardHolder multi = (MultiClipboardHolder) identifiable;
|
||||
multi.remove(uri);
|
||||
if (multi.getHolders().isEmpty()) session.setClipboard(null);
|
||||
} else {
|
||||
session.setClipboard(null);
|
||||
}
|
||||
BBC.CLIPBOARD_CLEARED.send(player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
BBC.CLIPBOARD_URI_NOT_FOUND.send(player, fileName);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"remap"},
|
||||
help = "Remap a clipboard between MCPE/PC values\n",
|
||||
@ -119,12 +190,15 @@ public class SchematicCommands extends MethodCommands {
|
||||
@Deprecated
|
||||
@CommandPermissions({"worldedit.schematic.remap"})
|
||||
public void remap(final Player player, final LocalSession session) throws WorldEditException {
|
||||
ClipboardHolder holder = session.getClipboard();
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
ClipboardRemapper remapper;
|
||||
if (Fawe.imp().getPlatform().equalsIgnoreCase("nukkit")) {
|
||||
new ClipboardRemapper(ClipboardRemapper.RemapPlatform.PC, ClipboardRemapper.RemapPlatform.PE).apply(clipboard);
|
||||
remapper = new ClipboardRemapper(ClipboardRemapper.RemapPlatform.PC, ClipboardRemapper.RemapPlatform.PE);
|
||||
} else {
|
||||
new ClipboardRemapper(ClipboardRemapper.RemapPlatform.PE, ClipboardRemapper.RemapPlatform.PC).apply(clipboard);
|
||||
remapper = new ClipboardRemapper(ClipboardRemapper.RemapPlatform.PE, ClipboardRemapper.RemapPlatform.PC);
|
||||
}
|
||||
|
||||
for (Clipboard clip : session.getClipboard().getClipboards()) {
|
||||
remapper.apply(clip);
|
||||
}
|
||||
player.print(BBC.getPrefix() + "Remapped schematic");
|
||||
}
|
||||
@ -141,6 +215,7 @@ public class SchematicCommands extends MethodCommands {
|
||||
}
|
||||
InputStream in = null;
|
||||
try {
|
||||
URI uri;
|
||||
if (filename.startsWith("url:")) {
|
||||
if (!player.hasPermission("worldedit.schematic.upload")) {
|
||||
BBC.NO_PERM.send(player, "worldedit.schematic.upload");
|
||||
@ -151,6 +226,7 @@ public class SchematicCommands extends MethodCommands {
|
||||
URL url = new URL(base, "uploads/" + uuid + ".schematic");
|
||||
ReadableByteChannel rbc = Channels.newChannel(url.openStream());
|
||||
in = Channels.newInputStream(rbc);
|
||||
uri = url.toURI();
|
||||
} else {
|
||||
if (!player.hasPermission("worldedit.schematic.load") && !player.hasPermission("worldedit.clipboard.load")) {
|
||||
BBC.NO_PERM.send(player, "worldedit.clipboard.load");
|
||||
@ -195,6 +271,8 @@ public class SchematicCommands extends MethodCommands {
|
||||
return;
|
||||
}
|
||||
in = new FileInputStream(f);
|
||||
|
||||
uri = f.toURI();
|
||||
}
|
||||
final ClipboardReader reader = format.getReader(in);
|
||||
final WorldData worldData = player.getWorld().getWorldData();
|
||||
@ -207,11 +285,11 @@ public class SchematicCommands extends MethodCommands {
|
||||
} else {
|
||||
clipboard = reader.read(player.getWorld().getWorldData());
|
||||
}
|
||||
session.setClipboard(new ClipboardHolder(clipboard, worldData));
|
||||
session.setClipboard(new URIClipboardHolder(uri, clipboard, worldData));
|
||||
BBC.SCHEMATIC_LOADED.send(player, filename);
|
||||
} catch (IllegalArgumentException e) {
|
||||
player.printError("Unknown filename: " + filename);
|
||||
} catch (IOException e) {
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
player.printError("File could not be read or it does not exist: " + e.getMessage());
|
||||
log.log(Level.WARNING, "Failed to load a saved clipboard", e);
|
||||
} finally {
|
||||
@ -345,12 +423,10 @@ public class SchematicCommands extends MethodCommands {
|
||||
m.send(actor);
|
||||
}
|
||||
|
||||
// schem list all|mine|global page
|
||||
|
||||
@Command(
|
||||
aliases = {"list", "all", "ls"},
|
||||
aliases = {"list", "ls", "all"},
|
||||
desc = "List saved schematics",
|
||||
usage = "[mine|<filter>] [page=1]",
|
||||
usage = "[global|mine|<filter>] [page=1]",
|
||||
min = 0,
|
||||
max = -1,
|
||||
flags = "dnp",
|
||||
@ -359,10 +435,69 @@ public class SchematicCommands extends MethodCommands {
|
||||
" -f <format> restricts by format\n"
|
||||
)
|
||||
@CommandPermissions("worldedit.schematic.list")
|
||||
public void list(Actor actor, CommandContext args, @Switch('p') @Optional("1") int page, @Switch('f') String formatName) throws WorldEditException {
|
||||
String baseCmd = Commands.getAlias(SchematicCommands.class, "schematic") + " " + Commands.getAlias(SchematicCommands.class, "load");
|
||||
File dir = worldEdit.getWorkingDirectoryFile(worldEdit.getConfiguration().saveDir);
|
||||
UtilityCommands.list(dir, actor, args, page, formatName, Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS, baseCmd);
|
||||
public void list(FawePlayer fp, Actor actor, CommandContext args, @Switch('p') @Optional("1") int page, @Switch('f') String formatName) throws WorldEditException {
|
||||
if (args.argsLength() == 0) {
|
||||
BBC.COMMAND_SYNTAX.send(fp, getCommand().usage());
|
||||
return;
|
||||
}
|
||||
LocalConfiguration config = worldEdit.getConfiguration();
|
||||
String prefix = config.noDoubleSlash ? "" : "/";
|
||||
File dir = worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||
|
||||
String schemCmd = prefix + Commands.getAlias(SchematicCommands.class, "schematic");
|
||||
String loadSingle = schemCmd + " " + Commands.getAlias(SchematicCommands.class, "load");
|
||||
String loadMulti = schemCmd + " " + Commands.getAlias(SchematicCommands.class, "loadall");
|
||||
String unload = schemCmd + " " + Commands.getAlias(SchematicCommands.class, "unload");
|
||||
String delete = schemCmd + " " + Commands.getAlias(SchematicCommands.class, "delete");
|
||||
String list = schemCmd + " " + Commands.getAlias(SchematicCommands.class, "list");
|
||||
|
||||
URIClipboardHolder multi = as(URIClipboardHolder.class, fp.getSession().getExistingClipboard());
|
||||
|
||||
UtilityCommands.list(dir, actor, args, page, formatName, Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS, new RunnableVal3<Message, URI, String>() {
|
||||
@Override
|
||||
public void run(Message msg, URI uri, String relFilePath) {
|
||||
boolean isDir = false;
|
||||
boolean loaded = multi != null && multi.contains(uri);
|
||||
|
||||
String name = relFilePath;
|
||||
String color;
|
||||
String uriStr = uri.toString();
|
||||
if (uriStr.startsWith("file:/")) {
|
||||
File file = new File(uri.getPath());
|
||||
name = file.getName();
|
||||
if (file.isDirectory()) {
|
||||
isDir = true;
|
||||
color = "&6";
|
||||
} else {
|
||||
color = "&a";
|
||||
}
|
||||
} else if (uriStr.startsWith("http://") || uriStr.startsWith("https://")) {
|
||||
// url
|
||||
color = "&9";
|
||||
} else {
|
||||
color = "&7";
|
||||
}
|
||||
|
||||
msg.text("&8 - ");
|
||||
|
||||
if (msg.supportsInteraction()) {
|
||||
if (loaded) {
|
||||
msg.text("&7[&c-&7]").command(unload + " " + relFilePath).tooltip("Unload this schematic");
|
||||
} else {
|
||||
msg.text("&7[&a+&7]").command(loadMulti + " " + relFilePath).tooltip("(WIP) Append this to your clipboard");
|
||||
}
|
||||
if (!isDir) msg.text("&7[&cX&7]").suggestTip("/" + delete + " " + relFilePath);
|
||||
msg.text(color + relFilePath);
|
||||
if (isDir) {
|
||||
msg.cmdTip(list + " " + args.getJoinedStrings(0) + " " + relFilePath);
|
||||
} else {
|
||||
msg.cmdTip(loadSingle + " " + relFilePath);
|
||||
}
|
||||
} else {
|
||||
msg.text(color).text(name);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
|
@ -21,6 +21,7 @@ package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.clipboard.URIClipboardHolder;
|
||||
import com.boydti.fawe.object.mask.IdMask;
|
||||
import com.boydti.fawe.object.regions.selector.FuzzyRegionSelector;
|
||||
import com.boydti.fawe.object.regions.selector.PolyhedralRegionSelector;
|
||||
@ -62,6 +63,10 @@ import com.sk89q.worldedit.util.formatting.StyledFragment;
|
||||
import com.sk89q.worldedit.util.formatting.component.CommandListBox;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.storage.ChunkStore;
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -578,16 +583,44 @@ public class SelectionCommands {
|
||||
@CommandPermissions("worldedit.selection.size")
|
||||
public void size(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
if (args.hasFlag('c')) {
|
||||
ClipboardHolder holder = session.getClipboard();
|
||||
ClipboardHolder root = session.getClipboard();
|
||||
// Clipboard clipboard = holder.getClipboard();
|
||||
int index = 0;
|
||||
for (ClipboardHolder holder : root.getHolders()) {
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
String name;
|
||||
if (holder instanceof URIClipboardHolder) {
|
||||
URI uri = ((URIClipboardHolder) holder).getUri();
|
||||
if (uri.toString().startsWith("file:/")) {
|
||||
name = new File(uri.getPath()).getName();
|
||||
} else {
|
||||
name = uri.getFragment();
|
||||
}
|
||||
} else {
|
||||
name = Integer.toString(index);
|
||||
}
|
||||
|
||||
Region region = clipboard.getRegion();
|
||||
Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint());
|
||||
Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(Vector.ONE);
|
||||
Vector origin = clipboard.getOrigin();
|
||||
|
||||
player.print(BBC.getPrefix() + "Cuboid dimensions (max - min): " + size);
|
||||
player.print(BBC.getPrefix() + "Offset: " + origin);
|
||||
player.print(BBC.getPrefix() + "Cuboid distance: " + size.distance(Vector.ONE));
|
||||
player.print(BBC.getPrefix() + "# of blocks: " + (int) (size.getX() * size.getY() * size.getZ()));
|
||||
String sizeStr = size.getBlockX() + "*" + size.getBlockY() + "*" + size.getBlockZ();
|
||||
String originStr = origin.getBlockX() + "," + origin.getBlockY() + "," + origin.getBlockZ();
|
||||
|
||||
long numBlocks = ((long) size.getBlockX() * size.getBlockY() * size.getBlockZ());
|
||||
|
||||
String msg = String.format("%1$s: %2$s @ %3$s (%4$d blocks)", name, sizeStr, originStr, numBlocks);
|
||||
player.print(BBC.getPrefix() + msg);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// player.print(BBC.getPrefix() + "Cuboid dimensions (max - min): " + size);
|
||||
// player.print(BBC.getPrefix() + "Offset: " + origin);
|
||||
// player.print(BBC.getPrefix() + "Cuboid distance: " + size.distance(Vector.ONE));
|
||||
// player.print(BBC.getPrefix() + "# of blocks: " + (int) (size.getX() * size.getY() * size.getZ()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -19,11 +19,13 @@
|
||||
|
||||
package com.sk89q.worldedit.command;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweAPI;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Commands;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.RunnableVal3;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.util.chat.Message;
|
||||
@ -75,6 +77,7 @@ import com.sk89q.worldedit.util.command.parametric.Optional;
|
||||
import com.sk89q.worldedit.util.command.parametric.ParametricCallable;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -87,7 +90,13 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@ -632,43 +641,98 @@ public class UtilityCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
public static void list(File dir, Actor actor, CommandContext args, @Range(min = 0) int page, String formatName, boolean playerFolder, String onClickCmd) {
|
||||
List<File> fileList = new ArrayList<>();
|
||||
list(dir, actor, args, page, formatName, playerFolder, new RunnableVal3<Message, URI, String>() {
|
||||
@Override
|
||||
public void run(Message m, URI uri, String fileName) {
|
||||
m.text(BBC.SCHEMATIC_LIST_ELEM, fileName, "");
|
||||
if (onClickCmd != null) m.cmdTip(onClickCmd + " " + fileName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void list(File dir, Actor actor, CommandContext args, @Range(min = 0) int page, String formatName, boolean playerFolder, RunnableVal3<Message, URI, String> eachMsg) {
|
||||
int len = args.argsLength();
|
||||
List<String> filters = new ArrayList<>();
|
||||
boolean mine = false;
|
||||
|
||||
String dirFilter = File.separator;
|
||||
|
||||
boolean listMine = false;
|
||||
boolean listGlobal = false;
|
||||
if (len > 0) {
|
||||
int max = len;
|
||||
if (MathMan.isInteger(args.getString(len - 1))) {
|
||||
page = args.getInteger(--len);
|
||||
}
|
||||
for (int i = 0; i < len; i++) {
|
||||
switch (args.getString(i).toLowerCase()) {
|
||||
String arg = args.getString(i);
|
||||
switch (arg.toLowerCase()) {
|
||||
case "me":
|
||||
case "mine":
|
||||
mine = true;
|
||||
case "local":
|
||||
case "private":
|
||||
listMine = true;
|
||||
break;
|
||||
case "public":
|
||||
case "global":
|
||||
listGlobal = true;
|
||||
break;
|
||||
case "all":
|
||||
listMine = true;
|
||||
listGlobal = true;
|
||||
break;
|
||||
default:
|
||||
filters.add(args.getString(i));
|
||||
if (arg.endsWith("/") || arg.endsWith(File.separator)) {
|
||||
arg = arg.replace("/", File.separator);
|
||||
String newDirFilter = dirFilter + arg;
|
||||
boolean exists = new File(dir, newDirFilter).exists() || playerFolder && new File(dir, actor.getUniqueId() + newDirFilter).exists();
|
||||
if (!exists) {
|
||||
arg = arg.substring(0, arg.length() - File.separator.length());
|
||||
if (arg.length() > 3 && arg.length() <= 16) {
|
||||
UUID fromName = Fawe.imp().getUUID(arg);
|
||||
if (fromName != null) {
|
||||
newDirFilter = dirFilter + fromName + File.separator;
|
||||
listGlobal = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
dirFilter = newDirFilter;
|
||||
}
|
||||
else {
|
||||
filters.add(arg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (playerFolder) {
|
||||
File playerDir = new File(dir, actor.getUniqueId().toString());
|
||||
if (playerDir.exists()) {
|
||||
fileList.addAll(allFiles(playerDir, true));
|
||||
if (!listMine && !listGlobal) {
|
||||
listMine = true;
|
||||
}
|
||||
if (!mine) {
|
||||
fileList.addAll(allFiles(dir, false));
|
||||
|
||||
FileFilter ignoreUUIDs = f -> {
|
||||
try {
|
||||
if (f.isDirectory()) {
|
||||
UUID uuid = UUID.fromString(f.getName());
|
||||
return false;
|
||||
}
|
||||
} catch (IllegalArgumentException exception) {}
|
||||
return true;
|
||||
};
|
||||
|
||||
List<File> fileList = new ArrayList<>();
|
||||
if (playerFolder) {
|
||||
if (listMine) {
|
||||
File playerDir = new File(dir, actor.getUniqueId() + dirFilter);
|
||||
if (playerDir.exists()) fileList.addAll(allFiles(playerDir.listFiles(), false));
|
||||
}
|
||||
if (listGlobal) {
|
||||
File rel = new File(dir, dirFilter);
|
||||
if (rel.exists()) fileList.addAll(allFiles(rel.listFiles(ignoreUUIDs), false));
|
||||
}
|
||||
} else {
|
||||
fileList.addAll(allFiles(dir, true));
|
||||
}
|
||||
if (!filters.isEmpty()) {
|
||||
for (String filter : filters) {
|
||||
fileList.removeIf(file -> !file.getPath().contains(filter));
|
||||
}
|
||||
File rel = new File(dir, dirFilter);
|
||||
if (rel.exists()) fileList.addAll(allFiles(rel.listFiles(), false));
|
||||
}
|
||||
|
||||
if (fileList.isEmpty()) {
|
||||
BBC.SCHEMATIC_NONE.send(actor);
|
||||
return;
|
||||
@ -680,10 +744,10 @@ public class UtilityCommands extends MethodCommands {
|
||||
.collect(Collectors.toList());
|
||||
|
||||
}
|
||||
File[] files = new File[fileList.size()];
|
||||
fileList.toArray(files);
|
||||
fileList = filter(fileList, filters);
|
||||
|
||||
final int perPage = actor instanceof Player ? 12 : 20; // More pages for console
|
||||
int pageCount = (files.length + perPage - 1) / perPage;
|
||||
int pageCount = (fileList.size() + perPage - 1) / perPage;
|
||||
if (page < 1) {
|
||||
BBC.SCHEMATIC_PAGE.send(actor, ">0");
|
||||
return;
|
||||
@ -695,9 +759,12 @@ public class UtilityCommands extends MethodCommands {
|
||||
|
||||
final int sortType = args.hasFlag('d') ? -1 : args.hasFlag('n') ? 1 : 0;
|
||||
// cleanup file list
|
||||
Arrays.sort(files, new Comparator<File>() {
|
||||
Collections.sort(fileList, new Comparator<File>() {
|
||||
@Override
|
||||
public int compare(File f1, File f2) {
|
||||
boolean dir1 = f1.isDirectory();
|
||||
boolean dir2 = f2.isDirectory();
|
||||
if (dir1 != dir2) return dir1 ? -1 : 1;
|
||||
int res;
|
||||
if (sortType == 0) { // use name by default
|
||||
int p = f1.getParent().compareTo(f2.getParent());
|
||||
@ -714,10 +781,9 @@ public class UtilityCommands extends MethodCommands {
|
||||
}
|
||||
});
|
||||
|
||||
List<String[]> schematics = listFiles(dir, files, playerFolder ? actor.getUniqueId() : null);
|
||||
int offset = (page - 1) * perPage;
|
||||
|
||||
int limit = Math.min(offset + perPage, schematics.size());
|
||||
int limit = Math.min(offset + perPage, fileList.size());
|
||||
|
||||
String fullArgs = (String) args.getLocals().get("arguments");
|
||||
String baseCmd = null;
|
||||
@ -726,12 +792,11 @@ public class UtilityCommands extends MethodCommands {
|
||||
}
|
||||
Message m = new Message(BBC.SCHEMATIC_LIST, page, pageCount);
|
||||
|
||||
UUID uuid = playerFolder ? actor.getUniqueId() : null;
|
||||
for (int i = offset; i < limit; i++) {
|
||||
String[] fileinfo = schematics.get(i);
|
||||
String fileName = fileinfo[0];
|
||||
String fileFormat = fileinfo[1];
|
||||
m.newline().text(BBC.SCHEMATIC_LIST_ELEM, fileName, fileFormat);
|
||||
if (onClickCmd != null) m.cmdTip(onClickCmd + " " + fileName);
|
||||
m.newline();
|
||||
File file = fileList.get(i);
|
||||
eachMsg.run(m, file.toURI(), getPath(dir, file, uuid));
|
||||
}
|
||||
if (baseCmd != null) {
|
||||
m.newline().paginate(baseCmd, page, pageCount);
|
||||
@ -739,16 +804,57 @@ public class UtilityCommands extends MethodCommands {
|
||||
m.send(actor);
|
||||
}
|
||||
|
||||
private static List<File> allFiles(File root, boolean recursive) {
|
||||
File[] files = root.listFiles();
|
||||
if (files == null) return new ArrayList<>();
|
||||
private static List<File> filter(List<File> fileList, List<String> filters) {
|
||||
|
||||
String[] normalizedNames = new String[fileList.size()];
|
||||
for (int i = 0; i < fileList.size(); i++) {
|
||||
String normalized = fileList.get(i).getName().toLowerCase();
|
||||
if (normalized.startsWith("../")) normalized = normalized.substring(3);
|
||||
normalizedNames[i] = normalized.replace("/", File.separator);
|
||||
}
|
||||
|
||||
for (String filter : filters) {
|
||||
if (fileList.isEmpty()) return fileList;
|
||||
String lowerFilter = filter.toLowerCase().replace("/", File.separator);
|
||||
List<File> newList = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < normalizedNames.length; i++) {
|
||||
if (normalizedNames[i].startsWith(lowerFilter)) newList.add(fileList.get(i));
|
||||
}
|
||||
if (newList.isEmpty()) {
|
||||
for (int i = 0; i < normalizedNames.length; i++) {
|
||||
if (normalizedNames[i].contains(lowerFilter)) newList.add(fileList.get(i));
|
||||
}
|
||||
|
||||
if (newList.isEmpty()) {
|
||||
String checkName = filter.replace("\\", "/").split("/")[0];
|
||||
if (checkName.length() > 3 && checkName.length() <= 16) {
|
||||
UUID fromName = Fawe.imp().getUUID(checkName);
|
||||
if (fromName != null) {
|
||||
lowerFilter = filter.replaceFirst(checkName, fromName.toString()).toLowerCase();
|
||||
for (int i = 0; i < normalizedNames.length; i++) {
|
||||
if (normalizedNames[i].startsWith(lowerFilter)) newList.add(fileList.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fileList = newList;
|
||||
}
|
||||
return fileList;
|
||||
}
|
||||
|
||||
private static List<File> allFiles(File[] files, boolean recursive) {
|
||||
if (files == null || files.length == 0) return Arrays.asList();
|
||||
List<File> fileList = new ArrayList<File>();
|
||||
for (File f : files) {
|
||||
if (f.isDirectory()) {
|
||||
if (recursive) {
|
||||
List<File> subFiles = allFiles(f, recursive);
|
||||
List<File> subFiles = allFiles(f.listFiles(), recursive);
|
||||
if (subFiles == null || subFiles.isEmpty()) continue; // empty subdir
|
||||
fileList.addAll(subFiles);
|
||||
} else {
|
||||
fileList.add(f);
|
||||
}
|
||||
} else {
|
||||
fileList.add(f);
|
||||
@ -757,34 +863,23 @@ public class UtilityCommands extends MethodCommands {
|
||||
return fileList;
|
||||
}
|
||||
|
||||
private static List<String[]> listFiles(File root, File[] files, UUID uuid) {
|
||||
// List Elem [ File Name, Format Name ]
|
||||
private static String getPath(File root, File file, UUID uuid) {
|
||||
File dir;
|
||||
if (uuid != null) {
|
||||
dir = new File(root, uuid.toString());
|
||||
} else {
|
||||
dir = root;
|
||||
}
|
||||
List<String[]> result = new ArrayList<>();
|
||||
for (File file : files) {
|
||||
|
||||
ClipboardFormat format = ClipboardFormat.findByFile(file);
|
||||
URI relative = dir.toURI().relativize(file.toURI());
|
||||
String name = "";
|
||||
StringBuilder name = new StringBuilder();
|
||||
if (relative.isAbsolute()) {
|
||||
relative = root.toURI().relativize(file.toURI());
|
||||
name += "../";
|
||||
name.append("../");
|
||||
}
|
||||
name += relative.getPath();
|
||||
String formatName;
|
||||
if (format == null) {
|
||||
String[] split = file.getName().split("\\.");
|
||||
formatName = split.length > 1 ? split[split.length - 1].toUpperCase() : "Unknown";
|
||||
} else {
|
||||
formatName = format.toString();
|
||||
}
|
||||
result.add(new String[] {name, formatName} );
|
||||
}
|
||||
return result;
|
||||
name.append(relative.getPath());
|
||||
return name.toString();
|
||||
}
|
||||
|
||||
public static void help(CommandContext args, WorldEdit we, Actor actor) {
|
||||
|
@ -207,7 +207,6 @@ public class WorldEditCommands {
|
||||
min = 0,
|
||||
max = -1
|
||||
)
|
||||
@CommandPermissions("worldedit.help")
|
||||
public void help(Actor actor, CommandContext args) throws WorldEditException {
|
||||
UtilityCommands.help(args, we, actor);
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
}
|
||||
}
|
||||
|
||||
default public void addSchems(Region region, Mask mask, WorldData worldData, ClipboardHolder[] clipboards, int rarity, boolean rotate) throws WorldEditException {
|
||||
default public void addSchems(Region region, Mask mask, WorldData worldData, List<ClipboardHolder> clipboards, int rarity, boolean rotate) throws WorldEditException {
|
||||
spawnResource(region, new SchemGen(mask, this, worldData, clipboards, rotate), rarity, 1);
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,8 @@ 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.clipboard.MultiClipboardHolder;
|
||||
import com.boydti.fawe.object.clipboard.URIClipboardHolder;
|
||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||
import com.boydti.fawe.object.io.PGZIPOutputStream;
|
||||
import com.boydti.fawe.object.io.ResettableFileInputStream;
|
||||
@ -50,7 +52,6 @@ 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;
|
||||
@ -61,6 +62,8 @@ import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
@ -315,7 +318,7 @@ public enum ClipboardFormat {
|
||||
});
|
||||
}
|
||||
|
||||
public ClipboardHolder[] loadAllFromInput(Actor player, WorldData worldData, String input, boolean message) throws IOException {
|
||||
public MultiClipboardHolder loadAllFromInput(Actor player, WorldData worldData, String input, boolean message) throws IOException {
|
||||
checkNotNull(player);
|
||||
checkNotNull(input);
|
||||
WorldEdit worldEdit = WorldEdit.getInstance();
|
||||
@ -327,7 +330,7 @@ public enum ClipboardFormat {
|
||||
if (message) BBC.WEB_UNAUTHORIZED.send(player, url);
|
||||
return null;
|
||||
}
|
||||
ClipboardHolder[] clipboards = loadAllFromUrl(url, worldData);
|
||||
MultiClipboardHolder clipboards = loadAllFromUrl(url, worldData);
|
||||
return clipboards;
|
||||
} else {
|
||||
if (input.contains("../") && !player.hasPermission("worldedit.schematic.load.other")) {
|
||||
@ -353,18 +356,19 @@ public enum ClipboardFormat {
|
||||
}
|
||||
if (!dir.isDirectory()) {
|
||||
ByteSource source = Files.asByteSource(dir);
|
||||
return new ClipboardHolder[]{new LazyClipboardHolder(source, this, worldData, null)};
|
||||
URI uri = dir.toURI();
|
||||
return new MultiClipboardHolder(uri, worldData, new LazyClipboardHolder(dir.toURI(), source, this, worldData, null));
|
||||
}
|
||||
ClipboardHolder[] clipboards = loadAllFromDirectory(dir, worldData);
|
||||
URIClipboardHolder[] clipboards = loadAllFromDirectory(dir, worldData);
|
||||
if (clipboards.length < 1) {
|
||||
if (message) BBC.SCHEMATIC_NOT_FOUND.send(player, input);
|
||||
return null;
|
||||
}
|
||||
return clipboards;
|
||||
return new MultiClipboardHolder(dir.toURI(), worldData, clipboards);
|
||||
}
|
||||
}
|
||||
|
||||
public ClipboardHolder[] loadAllFromDirectory(File dir, WorldData worldData) {
|
||||
public URIClipboardHolder[] loadAllFromDirectory(File dir, WorldData worldData) {
|
||||
if (worldData == null) {
|
||||
try {
|
||||
worldData = WorldEdit.getInstance().getServer().getWorlds().get(0).getWorldData();
|
||||
@ -381,12 +385,12 @@ public enum ClipboardFormat {
|
||||
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);
|
||||
clipboards[i] = new LazyClipboardHolder(file.toURI(), source, this, worldData, null);
|
||||
}
|
||||
return clipboards;
|
||||
}
|
||||
|
||||
public ClipboardHolder[] loadAllFromUrl(URL url, WorldData worldData) throws IOException {
|
||||
public MultiClipboardHolder 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)) {
|
||||
@ -402,14 +406,23 @@ public enum ClipboardFormat {
|
||||
}
|
||||
byte[] array = out.toByteArray();
|
||||
ByteSource source = ByteSource.wrap(array);
|
||||
LazyClipboardHolder clipboard = new LazyClipboardHolder(source, this, worldData, null);
|
||||
LazyClipboardHolder clipboard = new LazyClipboardHolder(url.toURI(), source, this, worldData, null);
|
||||
clipboards.add(clipboard);
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return clipboards.toArray(new LazyClipboardHolder[clipboards.size()]);
|
||||
LazyClipboardHolder[] arr = clipboards.toArray(new LazyClipboardHolder[clipboards.size()]);
|
||||
try {
|
||||
MultiClipboardHolder multi = new MultiClipboardHolder(url.toURI(), worldData);
|
||||
for (LazyClipboardHolder h : arr) multi.add(h);
|
||||
return multi;
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void write(OutputStream value, Clipboard clipboard) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.sk89q.worldedit.internal.expression.runtime;
|
||||
|
||||
import com.sk89q.worldedit.command.UtilityCommands;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.parser.ParserException;
|
||||
|
||||
@ -31,7 +30,7 @@ public class For extends Node {
|
||||
}
|
||||
|
||||
if(Thread.currentThread().isInterrupted()){
|
||||
throw new EvaluationException(this.getPosition(), "Thread has been interuppted.");
|
||||
throw new EvaluationException(this.getPosition(), "Thread has been interrupted.");
|
||||
}
|
||||
|
||||
++iterations;
|
||||
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.internal.expression.runtime;
|
||||
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.parser.ParserException;
|
||||
|
||||
/**
|
||||
* A simple-style for loop.
|
||||
*/
|
||||
public class SimpleFor extends Node {
|
||||
|
||||
LValue counter;
|
||||
RValue first;
|
||||
RValue last;
|
||||
RValue body;
|
||||
|
||||
public SimpleFor(int position, LValue counter, RValue first, RValue last, RValue body) {
|
||||
super(position);
|
||||
|
||||
this.counter = counter;
|
||||
this.first = first;
|
||||
this.last = last;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue() throws EvaluationException {
|
||||
int iterations = 0;
|
||||
double ret = 0.0;
|
||||
|
||||
double firstValue = first.getValue();
|
||||
double lastValue = last.getValue();
|
||||
|
||||
for (double i = firstValue; i <= lastValue; ++i) {
|
||||
if (iterations > 256) {
|
||||
throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations.");
|
||||
}
|
||||
if(Thread.currentThread().isInterrupted()){
|
||||
throw new EvaluationException(this.getPosition(), "Thread has been interrupted.");
|
||||
}
|
||||
++iterations;
|
||||
|
||||
try {
|
||||
counter.assign(i);
|
||||
ret = body.getValue();
|
||||
} catch (BreakException e) {
|
||||
if (e.doContinue) {
|
||||
//noinspection UnnecessaryContinue
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char id() {
|
||||
return 'S';
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "for (" + counter + " = " + first + ", " + last + ") { " + body + " }";
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue optimize() throws EvaluationException {
|
||||
// TODO: unroll small loops into Sequences
|
||||
|
||||
return new SimpleFor(getPosition(), counter.optimize(), first.optimize(), last.optimize(), body.optimize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException {
|
||||
counter = counter.bindVariables(expression, true);
|
||||
first = first.bindVariables(expression, false);
|
||||
last = last.bindVariables(expression, false);
|
||||
body = body.bindVariables(expression, false);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static Class<SimpleFor> inject() {
|
||||
return SimpleFor.class;
|
||||
}
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.internal.expression.runtime;
|
||||
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.parser.ParserException;
|
||||
|
||||
/**
|
||||
* A while loop.
|
||||
*/
|
||||
public class While extends Node {
|
||||
|
||||
RValue condition;
|
||||
RValue body;
|
||||
boolean footChecked;
|
||||
|
||||
public While(int position, RValue condition, RValue body, boolean footChecked) {
|
||||
super(position);
|
||||
|
||||
this.condition = condition;
|
||||
this.body = body;
|
||||
this.footChecked = footChecked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue() throws EvaluationException {
|
||||
int iterations = 0;
|
||||
double ret = 0.0;
|
||||
|
||||
if (footChecked) {
|
||||
do {
|
||||
if (iterations > 256) {
|
||||
throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations.");
|
||||
}
|
||||
if(Thread.currentThread().isInterrupted()){
|
||||
throw new EvaluationException(this.getPosition(), "Thread has been interrupted.");
|
||||
}
|
||||
++iterations;
|
||||
|
||||
try {
|
||||
ret = body.getValue();
|
||||
} catch (BreakException e) {
|
||||
if (e.doContinue) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (condition.getValue() > 0.0);
|
||||
} else {
|
||||
while (condition.getValue() > 0.0) {
|
||||
if (iterations > 256) {
|
||||
throw new EvaluationException(getPosition(), "Loop exceeded 256 iterations.");
|
||||
}
|
||||
if(Thread.currentThread().isInterrupted()){
|
||||
throw new EvaluationException(this.getPosition(), "Thread has been interrupted.");
|
||||
}
|
||||
++iterations;
|
||||
|
||||
try {
|
||||
ret = body.getValue();
|
||||
} catch (BreakException e) {
|
||||
if (e.doContinue) {
|
||||
//noinspection UnnecessaryContinue
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char id() {
|
||||
return 'w';
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (footChecked) {
|
||||
return "do { " + body + " } while (" + condition + ")";
|
||||
} else {
|
||||
return "while (" + condition + ") { " + body + " }";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue optimize() throws EvaluationException {
|
||||
final RValue newCondition = condition.optimize();
|
||||
|
||||
if (newCondition instanceof Constant && newCondition.getValue() <= 0) {
|
||||
// If the condition is always false, the loop can be flattened.
|
||||
if (footChecked) {
|
||||
// Foot-checked loops run at least once.
|
||||
return body.optimize();
|
||||
} else {
|
||||
// Loops that never run always return 0.0.
|
||||
return new Constant(getPosition(), 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
return new While(getPosition(), newCondition, body.optimize(), footChecked);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue bindVariables(Expression expression, boolean preferLValue) throws ParserException {
|
||||
condition = condition.bindVariables(expression, false);
|
||||
body = body.bindVariables(expression, false);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static Class<While> inject() {
|
||||
return While.class;
|
||||
}
|
||||
}
|
@ -25,6 +25,8 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.transform.Identity;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.world.registry.WorldData;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@ -33,7 +35,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
* Holds the clipboard and the current transform on the clipboard.
|
||||
*/
|
||||
public class ClipboardHolder {
|
||||
|
||||
private final WorldData worldData;
|
||||
private Clipboard clipboard;
|
||||
private Transform transform = new Identity();
|
||||
@ -70,12 +71,36 @@ public class ClipboardHolder {
|
||||
* If there is a transformation applied, the returned clipboard will
|
||||
* not contain its effect.
|
||||
*
|
||||
* @deprecated FAWE supports multiple loaded schematics {@link #getClipboards()}
|
||||
* @return the clipboard
|
||||
*/
|
||||
@Deprecated
|
||||
public Clipboard getClipboard() {
|
||||
return clipboard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all currently held clipboards
|
||||
* @return
|
||||
*/
|
||||
public List<Clipboard> getClipboards() {
|
||||
return Collections.singletonList(getClipboard());
|
||||
}
|
||||
|
||||
public boolean contains(Clipboard clipboard) {
|
||||
return this.clipboard == clipboard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all end ClipboardHolders<br/>
|
||||
* - Usually this will return itself.<br/>
|
||||
* - If this is a multi clipboard, it will return the children
|
||||
* @return Set of end ClipboardHolders
|
||||
*/
|
||||
public List<ClipboardHolder> getHolders() {
|
||||
return Collections.singletonList(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the transform.
|
||||
*
|
||||
|
@ -164,7 +164,6 @@ public class LevelDBToMCAFile extends MapConverter {
|
||||
case PendingTicks:
|
||||
break;
|
||||
case BlockExtraData:
|
||||
System.out.println("EXTRA " + chunk.getX() + "," + chunk.getZ());
|
||||
break;
|
||||
case LegacyTerrain:
|
||||
case Data2DLegacy:
|
||||
|
@ -1,3 +1,3 @@
|
||||
rootProject.name = 'FastAsyncWorldEdit'
|
||||
|
||||
include 'core', 'bukkit', 'favs', 'nukkit'//, 'forge1710', 'forge189', 'forge194', 'forge110', 'forge111', 'sponge', 'forge112', 'sponge111'
|
||||
include 'core', 'bukkit', 'favs', 'nukkit', 'forge1710', 'forge189', 'forge194', 'forge110', 'forge111', 'sponge', 'forge112', 'sponge111'
|
@ -22,7 +22,7 @@ buildscript {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'org.spongepowered.plugin' version '0.6'
|
||||
id 'org.spongepowered.plugin' version '0.8.1'
|
||||
}
|
||||
|
||||
apply plugin: 'net.minecrell.vanilla.server.library'
|
||||
@ -49,15 +49,14 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
compile 'org.spongepowered:spongeapi:6.1.0-SNAPSHOT'
|
||||
compile 'org.spongepowered:mixin:0.7-SNAPSHOT'
|
||||
compile 'com.sk89q.worldedit:worldedit-sponge:6.1.7-SNAPSHOT'
|
||||
compile name: 'worldedit-core-6.1.7-SNAPSHOT-dist'
|
||||
compile 'org.spongepowered:spongeapi:7.0.0-SNAPSHOT'
|
||||
compile name: 'worldedit-sponge-6.1.9-SNAPSHOT-dist'
|
||||
compile name: 'worldedit-core-6.1.9-SNAPSHOT-dist'
|
||||
}
|
||||
|
||||
minecraft {
|
||||
version = "1.12"
|
||||
mappings = "snapshot_20170726"
|
||||
mappings = "snapshot_20170713"
|
||||
runDir = 'run'
|
||||
}
|
||||
|
||||
|
BIN
sponge/lib/worldedit-core-6.1.9-SNAPSHOT-dist.jar
Normal file
BIN
sponge/lib/worldedit-core-6.1.9-SNAPSHOT-dist.jar
Normal file
Binary file not shown.
Binary file not shown.
@ -258,6 +258,7 @@ public class SpongeChunk_1_12 extends CharFaweChunk<Chunk, SpongeQueue_1_12> {
|
||||
}
|
||||
// Trim tiles
|
||||
if (!tiles.isEmpty()) {
|
||||
synchronized (SpongeChunk_1_12.class) {
|
||||
Set<Map.Entry<BlockPos, TileEntity>> entryset = tiles.entrySet();
|
||||
Iterator<Map.Entry<BlockPos, TileEntity>> iterator = entryset.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
@ -280,6 +281,7 @@ public class SpongeChunk_1_12 extends CharFaweChunk<Chunk, SpongeQueue_1_12> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HashSet<UUID> entsToRemove = this.getEntityRemoves();
|
||||
if (!entsToRemove.isEmpty()) {
|
||||
synchronized (SpongeChunk_1_12.class) {
|
||||
|
@ -258,6 +258,7 @@ public class SpongeChunk_1_11 extends CharFaweChunk<Chunk, SpongeQueue_1_11> {
|
||||
}
|
||||
// Trim tiles
|
||||
if (!tiles.isEmpty()) {
|
||||
synchronized (SpongeChunk_1_11.class) {
|
||||
Set<Map.Entry<BlockPos, TileEntity>> entryset = tiles.entrySet();
|
||||
Iterator<Map.Entry<BlockPos, TileEntity>> iterator = entryset.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
@ -280,6 +281,7 @@ public class SpongeChunk_1_11 extends CharFaweChunk<Chunk, SpongeQueue_1_11> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HashSet<UUID> entsToRemove = this.getEntityRemoves();
|
||||
if (!entsToRemove.isEmpty()) {
|
||||
synchronized (SpongeChunk_1_11.class) {
|
||||
|
Loading…
Reference in New Issue
Block a user