mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-06-11 20:13:55 +00:00
Plenty of changes to core block behavior to become more compatible with upstream WorldEdit (still more to be done!)
This commit is contained in:
@ -79,7 +79,7 @@ public class LazyBlock extends BaseBlock {
|
||||
@Override
|
||||
public CompoundTag getNbtData() {
|
||||
if (!loaded) {
|
||||
BlockState loadedBlock = extent.getFullBlock(position);
|
||||
BlockState loadedBlock = extent.getFullBlock(position).toImmutableState();
|
||||
this.nbtData = loadedBlock.getNbtData();
|
||||
loaded = true;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import com.sk89q.worldedit.internal.registry.AbstractFactory;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
@ -222,7 +223,7 @@ public class FaweAPI {
|
||||
* @see com.boydti.fawe.object.schematic.Schematic
|
||||
*/
|
||||
public static Schematic load(File file) throws IOException {
|
||||
return ClipboardFormat.SCHEMATIC.load(file);
|
||||
return ClipboardFormats.findByFile(file).load(file);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,7 +22,6 @@ import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.pattern.RandomPattern;
|
||||
|
@ -36,7 +36,9 @@ 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.BuiltInClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
@ -502,7 +504,7 @@ public class CFICommands extends MethodCommands {
|
||||
HeightMapMCAGenerator gen = assertSettings(fp).getGenerator();
|
||||
|
||||
World world = fp.getWorld();
|
||||
MultiClipboardHolder multi = ClipboardFormat.SCHEMATIC.loadAllFromInput(fp.getPlayer(), schematic, null, true);
|
||||
MultiClipboardHolder multi = ClipboardFormats.loadAllFromInput(fp.getPlayer(), schematic, null, true);
|
||||
if (multi == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -202,10 +202,10 @@ public abstract class IntFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
}
|
||||
vs[j] = combinedId;
|
||||
this.count[i]++;
|
||||
switch (BlockTypes.getFromStateId(combinedId)) {
|
||||
case AIR:
|
||||
case CAVE_AIR:
|
||||
case VOID_AIR:
|
||||
switch (BlockTypes.getFromStateId(combinedId).getResource().toUpperCase()) {
|
||||
case "AIR":
|
||||
case "CAVE_AIR":
|
||||
case "VOID_AIR":
|
||||
this.air[i]++;
|
||||
return;
|
||||
default:
|
||||
|
@ -201,25 +201,25 @@ public class SchematicStreamer extends NBTStreamer {
|
||||
fc.forEach(new FaweClipboard.BlockReader() {
|
||||
@Override
|
||||
public void run(int x, int y, int z, BlockState block) {
|
||||
BlockTypes type = block.getBlockType();
|
||||
switch (type) {
|
||||
case ACACIA_STAIRS:
|
||||
case BIRCH_STAIRS:
|
||||
case BRICK_STAIRS:
|
||||
case COBBLESTONE_STAIRS:
|
||||
case DARK_OAK_STAIRS:
|
||||
case DARK_PRISMARINE_STAIRS:
|
||||
case JUNGLE_STAIRS:
|
||||
case NETHER_BRICK_STAIRS:
|
||||
case OAK_STAIRS:
|
||||
case PRISMARINE_BRICK_STAIRS:
|
||||
case PRISMARINE_STAIRS:
|
||||
case PURPUR_STAIRS:
|
||||
case QUARTZ_STAIRS:
|
||||
case RED_SANDSTONE_STAIRS:
|
||||
case SANDSTONE_STAIRS:
|
||||
case SPRUCE_STAIRS:
|
||||
case STONE_BRICK_STAIRS:
|
||||
BlockType type = block.getBlockType();
|
||||
switch (type.getResource().toUpperCase()) {
|
||||
case "ACACIA_STAIRS":
|
||||
case "BIRCH_STAIRS":
|
||||
case "BRICK_STAIRS":
|
||||
case "COBBLESTONE_STAIRS":
|
||||
case "DARK_OAK_STAIRS":
|
||||
case "DARK_PRISMARINE_STAIRS":
|
||||
case "JUNGLE_STAIRS":
|
||||
case "NETHER_BRICK_STAIRS":
|
||||
case "OAK_STAIRS":
|
||||
case "PRISMARINE_BRICK_STAIRS":
|
||||
case "PRISMARINE_STAIRS":
|
||||
case "PURPUR_STAIRS":
|
||||
case "QUARTZ_STAIRS":
|
||||
case "RED_SANDSTONE_STAIRS":
|
||||
case "SANDSTONE_STAIRS":
|
||||
case "SPRUCE_STAIRS":
|
||||
case "STONE_BRICK_STAIRS":
|
||||
Object half = block.getState(PropertyKey.HALF);
|
||||
Direction facing = block.getState(PropertyKey.FACING);
|
||||
|
||||
@ -228,19 +228,19 @@ public class SchematicStreamer extends NBTStreamer {
|
||||
Direction right = facing.getRight();
|
||||
|
||||
BlockStateHolder forwardBlock = fc.getBlock(x + forward.getBlockX(), y + forward.getBlockY(), z + forward.getBlockZ());
|
||||
BlockTypes forwardType = forwardBlock.getBlockType();
|
||||
BlockType forwardType = forwardBlock.getBlockType();
|
||||
if (forwardType.hasProperty(PropertyKey.SHAPE) && forwardType.hasProperty(PropertyKey.FACING)) {
|
||||
Direction forwardFacing = (Direction) forwardBlock.getState(PropertyKey.FACING);
|
||||
if (forwardFacing == left) {
|
||||
BlockStateHolder rightBlock = fc.getBlock(x + right.getBlockX(), y + right.getBlockY(), z + right.getBlockZ());
|
||||
BlockTypes rightType = rightBlock.getBlockType();
|
||||
BlockType rightType = rightBlock.getBlockType();
|
||||
if (!rightType.hasProperty(PropertyKey.SHAPE) || rightBlock.getState(PropertyKey.FACING) != facing) {
|
||||
fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "inner_left"));
|
||||
}
|
||||
return;
|
||||
} else if (forwardFacing == right) {
|
||||
BlockStateHolder leftBlock = fc.getBlock(x + left.getBlockX(), y + left.getBlockY(), z + left.getBlockZ());
|
||||
BlockTypes leftType = leftBlock.getBlockType();
|
||||
BlockType leftType = leftBlock.getBlockType();
|
||||
if (!leftType.hasProperty(PropertyKey.SHAPE) || leftBlock.getState(PropertyKey.FACING) != facing) {
|
||||
fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "inner_right"));
|
||||
}
|
||||
@ -249,19 +249,19 @@ public class SchematicStreamer extends NBTStreamer {
|
||||
}
|
||||
|
||||
BlockStateHolder backwardsBlock = fc.getBlock(x - forward.getBlockX(), y - forward.getBlockY(), z - forward.getBlockZ());
|
||||
BlockTypes backwardsType = backwardsBlock.getBlockType();
|
||||
BlockType backwardsType = backwardsBlock.getBlockType();
|
||||
if (backwardsType.hasProperty(PropertyKey.SHAPE) && backwardsType.hasProperty(PropertyKey.FACING)) {
|
||||
Direction backwardsFacing = (Direction) backwardsBlock.getState(PropertyKey.FACING);
|
||||
if (backwardsFacing == left) {
|
||||
BlockStateHolder rightBlock = fc.getBlock(x + right.getBlockX(), y + right.getBlockY(), z + right.getBlockZ());
|
||||
BlockTypes rightType = rightBlock.getBlockType();
|
||||
BlockType rightType = rightBlock.getBlockType();
|
||||
if (!rightType.hasProperty(PropertyKey.SHAPE) || rightBlock.getState(PropertyKey.FACING) != facing) {
|
||||
fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "outer_left"));
|
||||
}
|
||||
return;
|
||||
} else if (backwardsFacing == right) {
|
||||
BlockStateHolder leftBlock = fc.getBlock(x + left.getBlockX(), y + left.getBlockY(), z + left.getBlockZ());
|
||||
BlockTypes leftType = leftBlock.getBlockType();
|
||||
BlockType leftType = leftBlock.getBlockType();
|
||||
if (!leftType.hasProperty(PropertyKey.SHAPE) || leftBlock.getState(PropertyKey.FACING) != facing) {
|
||||
fc.setBlock(x, y, z, block.with(PropertyKey.SHAPE, "outer_right"));
|
||||
}
|
||||
@ -301,43 +301,43 @@ public class SchematicStreamer extends NBTStreamer {
|
||||
|
||||
private boolean merge(int group, int x, int y, int z) {
|
||||
BlockStateHolder block = fc.getBlock(x, y, z);
|
||||
BlockTypes type = block.getBlockType();
|
||||
BlockType type = block.getBlockType();
|
||||
return group(type) == group || fullCube.apply(type);
|
||||
}
|
||||
|
||||
private int group(BlockTypes type) {
|
||||
switch (type) {
|
||||
case ACACIA_FENCE:
|
||||
case BIRCH_FENCE:
|
||||
case DARK_OAK_FENCE:
|
||||
case JUNGLE_FENCE:
|
||||
case OAK_FENCE:
|
||||
case SPRUCE_FENCE:
|
||||
private int group(BlockType type) {
|
||||
switch (type.getResource().toUpperCase()) {
|
||||
case "ACACIA_FENCE":
|
||||
case "BIRCH_FENCE":
|
||||
case "DARK_OAK_FENCE":
|
||||
case "JUNGLE_FENCE":
|
||||
case "OAK_FENCE":
|
||||
case "SPRUCE_FENCE":
|
||||
return 0;
|
||||
case NETHER_BRICK_FENCE:
|
||||
case "NETHER_BRICK_FENCE":
|
||||
return 1;
|
||||
case COBBLESTONE_WALL:
|
||||
case MOSSY_COBBLESTONE_WALL:
|
||||
case "COBBLESTONE_WALL":
|
||||
case "MOSSY_COBBLESTONE_WALL":
|
||||
return 2;
|
||||
case IRON_BARS:
|
||||
case BLACK_STAINED_GLASS_PANE:
|
||||
case BLUE_STAINED_GLASS_PANE:
|
||||
case BROWN_MUSHROOM_BLOCK:
|
||||
case BROWN_STAINED_GLASS_PANE:
|
||||
case CYAN_STAINED_GLASS_PANE:
|
||||
case GLASS_PANE:
|
||||
case GRAY_STAINED_GLASS_PANE:
|
||||
case GREEN_STAINED_GLASS_PANE:
|
||||
case LIGHT_BLUE_STAINED_GLASS_PANE:
|
||||
case LIGHT_GRAY_STAINED_GLASS_PANE:
|
||||
case LIME_STAINED_GLASS_PANE:
|
||||
case MAGENTA_STAINED_GLASS_PANE:
|
||||
case ORANGE_STAINED_GLASS_PANE:
|
||||
case PINK_STAINED_GLASS_PANE:
|
||||
case PURPLE_STAINED_GLASS_PANE:
|
||||
case RED_STAINED_GLASS_PANE:
|
||||
case WHITE_STAINED_GLASS_PANE:
|
||||
case YELLOW_STAINED_GLASS_PANE:
|
||||
case "IRON_BARS":
|
||||
case "BLACK_STAINED_GLASS_PANE":
|
||||
case "BLUE_STAINED_GLASS_PANE":
|
||||
case "BROWN_MUSHROOM_BLOCK":
|
||||
case "BROWN_STAINED_GLASS_PANE":
|
||||
case "CYAN_STAINED_GLASS_PANE":
|
||||
case "GLASS_PANE":
|
||||
case "GRAY_STAINED_GLASS_PANE":
|
||||
case "GREEN_STAINED_GLASS_PANE":
|
||||
case "LIGHT_BLUE_STAINED_GLASS_PANE":
|
||||
case "LIGHT_GRAY_STAINED_GLASS_PANE":
|
||||
case "LIME_STAINED_GLASS_PANE":
|
||||
case "MAGENTA_STAINED_GLASS_PANE":
|
||||
case "ORANGE_STAINED_GLASS_PANE":
|
||||
case "PINK_STAINED_GLASS_PANE":
|
||||
case "PURPLE_STAINED_GLASS_PANE":
|
||||
case "RED_STAINED_GLASS_PANE":
|
||||
case "WHITE_STAINED_GLASS_PANE":
|
||||
case "YELLOW_STAINED_GLASS_PANE":
|
||||
return 3;
|
||||
default:
|
||||
return -1;
|
||||
@ -450,6 +450,7 @@ public class SchematicStreamer extends NBTStreamer {
|
||||
|
||||
public Clipboard getClipboard() throws IOException {
|
||||
try {
|
||||
setupClipboard(0);
|
||||
addDimensionReaders();
|
||||
addBlockReaders();
|
||||
readFully();
|
||||
|
@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.TextureUtil;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
@ -80,12 +81,12 @@ public final class HeightMapMCADrawer {
|
||||
if (height + 1 < waterHeight) {
|
||||
int waterId = gen.primtives.waterId;
|
||||
int waterColor = 0;
|
||||
BlockTypes waterType = BlockTypes.get(waterId);
|
||||
switch (waterType) {
|
||||
case WATER:
|
||||
BlockType waterType = BlockTypes.get(waterId);
|
||||
switch (waterType.getResource().toUpperCase()) {
|
||||
case "WATER":
|
||||
color = tu.averageColor((0x11 << 16) + (0x66 << 8) + (0xCC), color);
|
||||
break;
|
||||
case LAVA:
|
||||
case "LAVA":
|
||||
color = (0xCC << 16) + (0x33 << 8) + (0);
|
||||
break;
|
||||
default:
|
||||
|
@ -445,9 +445,9 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
||||
|
||||
private final void setLayerHeight(int index, int blockHeight, int layerHeight) {
|
||||
int floorState = floor.get()[index];
|
||||
switch (BlockTypes.getFromStateId(floorState)) {
|
||||
case SNOW:
|
||||
case SNOW_BLOCK:
|
||||
switch (BlockTypes.getFromStateId(floorState).getResource().toUpperCase()) {
|
||||
case "SNOW":
|
||||
case "SNOW_BLOCK":
|
||||
if (layerHeight != 0) {
|
||||
this.heights.setByte(index, (byte) (blockHeight + 1));
|
||||
this.floor.setInt(index, (BlockTypes.SNOW.getInternalId() + layerHeight));
|
||||
@ -470,9 +470,9 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
|
||||
|
||||
private final void setLayerHeightRaw(int index, int blockHeight, int layerHeight) {
|
||||
int floorState = floor.get()[index];
|
||||
switch (BlockTypes.getFromStateId(floorState)) {
|
||||
case SNOW:
|
||||
case SNOW_BLOCK:
|
||||
switch (BlockTypes.getFromStateId(floorState).getResource().toUpperCase()) {
|
||||
case "SNOW":
|
||||
case "SNOW_BLOCK":
|
||||
if (layerHeight != 0) {
|
||||
this.heights.getByteArray()[index] = (byte) (blockHeight + 1);
|
||||
this.floor.getIntArray()[index] = (BlockTypes.SNOW.getInternalId() + layerHeight);
|
||||
|
@ -172,9 +172,9 @@ public class CavesGen extends GenBase {
|
||||
if ((d11 > -0.7D) && (d9 * d9 + d11 * d11 + d10 * d10 < 1.0D)) {
|
||||
BlockStateHolder material = chunk.getLazyBlock(bx + local_x, local_y, bz + local_z);
|
||||
BlockStateHolder materialAbove = chunk.getLazyBlock(bx + local_x, local_y + 1, bz + local_z);
|
||||
switch (material.getBlockType()) {
|
||||
case GRASS:
|
||||
case MYCELIUM:
|
||||
switch (material.getBlockType().getResource().toUpperCase()) {
|
||||
case "GRASS":
|
||||
case "MYCELIUM":
|
||||
grassFound = true;
|
||||
break;
|
||||
}
|
||||
@ -205,13 +205,13 @@ public class CavesGen extends GenBase {
|
||||
}
|
||||
|
||||
protected boolean isSuitableBlock(BlockStateHolder material, BlockStateHolder materialAbove) {
|
||||
switch (material.getBlockType()) {
|
||||
case AIR:
|
||||
case CAVE_AIR:
|
||||
case VOID_AIR:
|
||||
case WATER:
|
||||
case LAVA:
|
||||
case BEDROCK:
|
||||
switch (material.getBlockType().getResource().toUpperCase()) {
|
||||
case "AIR":
|
||||
case "CAVE_AIR":
|
||||
case "VOID_AIR":
|
||||
case "WATER":
|
||||
case "LAVA":
|
||||
case "BEDROCK":
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
|
@ -5,6 +5,7 @@ import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||
import com.boydti.fawe.object.queue.DelegateFaweQueue;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
public class ChangeSetFaweQueue extends DelegateFaweQueue {
|
||||
@ -28,7 +29,7 @@ public class ChangeSetFaweQueue extends DelegateFaweQueue {
|
||||
|
||||
if (super.setBlock(x, y, z, combinedId)) {
|
||||
int combinedFrom = getParent().getCombinedId4Data(x, y, z);
|
||||
BlockTypes typeFrom = BlockTypes.getFromStateId(combinedFrom);
|
||||
BlockType typeFrom = BlockTypes.getFromStateId(combinedFrom);
|
||||
if (typeFrom.getMaterial().hasContainer()) {
|
||||
CompoundTag nbt = getParent().getTileEntity(x, y, z);
|
||||
if (nbt != null) {
|
||||
|
@ -120,7 +120,7 @@ public abstract class FaweChunk<T> implements Callable<FaweChunk> {
|
||||
try {
|
||||
CompoundTag tile = getTile(x & 15, y, z & 15);
|
||||
if (tile != null) {
|
||||
return BaseBlock.getFromInternalId(combined, tile);
|
||||
return BaseBlock.getFromInternalId(combined, tile).toImmutableState();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
|
@ -23,6 +23,7 @@ import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.io.File;
|
||||
@ -78,7 +79,7 @@ public interface FaweQueue extends HasFaweQueue, Extent {
|
||||
if (state.getMaterial().hasContainer()) {
|
||||
CompoundTag tile = getTileEntity(x, y, z);
|
||||
if (tile != null) {
|
||||
return BaseBlock.getFromInternalId(combinedId4Data, tile);
|
||||
return BaseBlock.getFromInternalId(combinedId4Data, tile).toImmutableState();
|
||||
}
|
||||
}
|
||||
return state;
|
||||
@ -94,8 +95,8 @@ public interface FaweQueue extends HasFaweQueue, Extent {
|
||||
}
|
||||
|
||||
@Override
|
||||
default BlockState getFullBlock(BlockVector3 position) {
|
||||
return getLazyBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ());
|
||||
default BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return getLazyBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ()).toBaseBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -275,18 +276,18 @@ public interface FaweQueue extends HasFaweQueue, Extent {
|
||||
for (int y = 0; y <= getMaxY(); y++) {
|
||||
int combined = getCombinedId4Data(xx, y, zz);
|
||||
BlockState state = BlockState.getFromInternalId(combined);
|
||||
BlockTypes type = state.getBlockType();
|
||||
switch (type.getTypeEnum()) {
|
||||
case AIR:
|
||||
case VOID_AIR:
|
||||
case CAVE_AIR:
|
||||
BlockType type = state.getBlockType();
|
||||
switch (type.getResource().toUpperCase()) {
|
||||
case "AIR":
|
||||
case "VOID_AIR":
|
||||
case "CAVE_AIR":
|
||||
continue;
|
||||
}
|
||||
mutable.mutY(y);
|
||||
CompoundTag tile = getTileEntity(x, y, z);
|
||||
if (tile != null) {
|
||||
BaseBlock block = BaseBlock.getFromInternalId(combined, tile);
|
||||
onEach.run(mutable.toBlockVector3(), block);
|
||||
onEach.run(mutable.toBlockVector3(), block.toImmutableState());
|
||||
} else {
|
||||
onEach.run(mutable.toBlockVector3(), state);
|
||||
}
|
||||
@ -308,7 +309,7 @@ public interface FaweQueue extends HasFaweQueue, Extent {
|
||||
if (combined == 0) {
|
||||
continue;
|
||||
}
|
||||
BlockTypes type = BlockTypes.getFromStateId(combined);
|
||||
BlockType type = BlockTypes.getFromStateId(combined);
|
||||
if (type.getMaterial().hasContainer()) {
|
||||
CompoundTag tile = getTileEntity(x, y, z);
|
||||
if (tile != null) {
|
||||
@ -316,7 +317,7 @@ public interface FaweQueue extends HasFaweQueue, Extent {
|
||||
mutable.mutZ(zz);
|
||||
mutable.mutY(y);
|
||||
BaseBlock block = BaseBlock.getFromInternalId(combined, tile);
|
||||
onEach.run(mutable.toBlockVector3(), block);
|
||||
onEach.run(mutable.toBlockVector3(), block.toImmutableState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,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.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import java.io.IOException;
|
||||
@ -34,7 +35,7 @@ public abstract class ScrollAction implements ScrollTool {
|
||||
}
|
||||
String filename = split[1];
|
||||
try {
|
||||
MultiClipboardHolder multi = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, filename, null, message);
|
||||
MultiClipboardHolder multi = ClipboardFormats.loadAllFromInput(player, filename, null, message);
|
||||
if (multi == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import com.sk89q.worldedit.event.platform.PlayerInputEvent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.world.SimpleWorld;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
@ -22,8 +23,8 @@ public interface VirtualWorld extends SimpleWorld, FaweQueue, Closeable {
|
||||
FaweChunk getSnapshot(int chunkX, int chunkZ);
|
||||
|
||||
@Override
|
||||
default BlockState getFullBlock(BlockVector3 position) {
|
||||
return getLazyBlock(position);
|
||||
default BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return getLazyBlock(position).toBaseBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -115,10 +115,10 @@ public class VisualChunk extends FaweChunk<FaweChunk> {
|
||||
public void setBlock(int x, int y, int z, int combinedId) {
|
||||
int index = getIndex(x, y, z);
|
||||
try {
|
||||
switch (BlockTypes.getFromStateId(combinedId)) {
|
||||
case AIR:
|
||||
case CAVE_AIR:
|
||||
case VOID_AIR:
|
||||
switch (BlockTypes.getFromStateId(combinedId).getResource().toUpperCase()) {
|
||||
case "AIR":
|
||||
case "CAVE_AIR":
|
||||
case "VOID_AIR":
|
||||
add.clear(index);
|
||||
remove.set(index);
|
||||
break;
|
||||
|
@ -11,6 +11,7 @@ import com.sk89q.worldedit.extent.inventory.BlockBagException;
|
||||
import com.sk89q.worldedit.history.UndoContext;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
public class MutableFullBlockChange implements Change {
|
||||
@ -60,9 +61,9 @@ public class MutableFullBlockChange implements Change {
|
||||
}
|
||||
|
||||
public void perform(FaweQueue queue) {
|
||||
BlockTypes idFrom = BlockTypes.getFromStateId(from);
|
||||
BlockType idFrom = BlockTypes.getFromStateId(from);
|
||||
if (blockBag != null) {
|
||||
BlockTypes idTo = BlockTypes.getFromStateId(to);
|
||||
BlockType idTo = BlockTypes.getFromStateId(to);
|
||||
if (idFrom != idTo) {
|
||||
if (allowFetch && from != 0) {
|
||||
try {
|
||||
|
@ -17,6 +17,7 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -147,12 +148,12 @@ public class CPUOptimizedClipboard extends FaweClipboard {
|
||||
@Override
|
||||
public BlockState getBlock(int index) {
|
||||
int combinedId = states[index];
|
||||
BlockTypes type = BlockTypes.getFromStateId(combinedId);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
BlockState state = type.withStateId(combinedId);
|
||||
if (type.getMaterial().hasContainer()) {
|
||||
CompoundTag nbt = getTag(index);
|
||||
if (nbt != null) {
|
||||
return new BaseBlock(state, nbt);
|
||||
return new BaseBlock(state, nbt).toImmutableState();
|
||||
}
|
||||
}
|
||||
return state;
|
||||
@ -174,10 +175,10 @@ public class CPUOptimizedClipboard extends FaweClipboard {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, index++) {
|
||||
BlockState block = getBlock(index);
|
||||
switch (block.getBlockType()) {
|
||||
case AIR:
|
||||
case CAVE_AIR:
|
||||
case VOID_AIR:
|
||||
switch (block.getBlockType().getResource().toUpperCase()) {
|
||||
case "AIR":
|
||||
case "CAVE_AIR":
|
||||
case "VOID_AIR":
|
||||
continue;
|
||||
default:
|
||||
task.run(x, y, z, block);
|
||||
|
@ -21,6 +21,7 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.io.Closeable;
|
||||
@ -371,14 +372,14 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, pos += 4) {
|
||||
int combinedId = mbb.getInt(pos);
|
||||
BlockTypes type = BlockTypes.getFromStateId(combinedId);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
BlockState state = type.withStateId(combinedId);
|
||||
if (type.getMaterial().hasContainer()) {
|
||||
trio.set(x, y, z);
|
||||
CompoundTag nbt = nbtMap.get(trio);
|
||||
if (nbt != null) {
|
||||
BaseBlock block = new BaseBlock(state, nbt);
|
||||
task.run(x, y, z, block);
|
||||
task.run(x, y, z, block.toImmutableState());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -402,11 +403,11 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, pos += 4) {
|
||||
int combinedId = mbb.getInt(pos);
|
||||
BlockTypes type = BlockTypes.getFromStateId(combinedId);
|
||||
switch (type) {
|
||||
case AIR:
|
||||
case CAVE_AIR:
|
||||
case VOID_AIR:
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
switch (type.getResource().toUpperCase()) {
|
||||
case "AIR":
|
||||
case "CAVE_AIR":
|
||||
case "VOID_AIR":
|
||||
continue;
|
||||
default:
|
||||
BlockState state = type.withStateId(combinedId);
|
||||
@ -415,7 +416,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
CompoundTag nbt = nbtMap.get(trio);
|
||||
if (nbt != null) {
|
||||
BaseBlock block = new BaseBlock(state, nbt);
|
||||
task.run(x, y, z, block);
|
||||
task.run(x, y, z, block.toImmutableState());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -436,12 +437,12 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
try {
|
||||
int index = HEADER_SIZE + (getIndex(x, y, z) << 2);
|
||||
int combinedId = mbb.getInt(index);
|
||||
BlockTypes type = BlockTypes.getFromStateId(combinedId);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
BlockState state = type.withStateId(combinedId);
|
||||
if (type.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
|
||||
CompoundTag nbt = nbtMap.get(new IntegerTrio(x, y, z));
|
||||
if (nbt != null) {
|
||||
return new BaseBlock(state, nbt);
|
||||
return new BaseBlock(state, nbt).toImmutableState();
|
||||
}
|
||||
}
|
||||
return state;
|
||||
@ -458,7 +459,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
try {
|
||||
int diskIndex = (HEADER_SIZE) + (i << 2);
|
||||
int combinedId = mbb.getInt(diskIndex);
|
||||
BlockTypes type = BlockTypes.getFromStateId(combinedId);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
BlockState state = type.withStateId(combinedId);
|
||||
if (type.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
|
||||
CompoundTag nbt;
|
||||
@ -481,7 +482,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
nbt = nbtMap.get(new IntegerTrio(x, y, z));
|
||||
}
|
||||
if (nbt != null) {
|
||||
return new BaseBlock(state, nbt);
|
||||
return new BaseBlock(state, nbt).toImmutableState();
|
||||
}
|
||||
}
|
||||
return state;
|
||||
|
@ -2,6 +2,7 @@ package com.boydti.fawe.object.clipboard;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
@ -73,8 +74,8 @@ public class EmptyClipboard implements Clipboard {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getFullBlock(BlockVector3 position) {
|
||||
return EditSession.nullBlock;
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return EditSession.nullBlock.toBaseBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -18,6 +18,7 @@ import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import net.jpountz.util.SafeUtils;
|
||||
|
||||
@ -203,10 +204,11 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
}
|
||||
}
|
||||
if (lastCombinedIds == null) {
|
||||
switch (BlockTypes.getFromStateId(v)) {
|
||||
case AIR:
|
||||
case CAVE_AIR:
|
||||
case VOID_AIR:
|
||||
BlockType bt = BlockTypes.getFromStateId(v);
|
||||
switch (bt.getResource().toUpperCase()) {
|
||||
case "AIR":
|
||||
case "CAVE_AIR":
|
||||
case "VOID_AIR":
|
||||
return;
|
||||
}
|
||||
lastCombinedIds = new byte[BLOCK_SIZE];
|
||||
@ -270,12 +272,12 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
@Override
|
||||
public BlockState getBlock(int index) {
|
||||
int combinedId = getCombinedId(index);
|
||||
BlockTypes type = BlockTypes.getFromStateId(combinedId);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
BlockState state = type.withStateId(combinedId);
|
||||
if (type.getMaterial().hasContainer()) {
|
||||
CompoundTag nbt = getTag(index);
|
||||
if (nbt != null) {
|
||||
return new BaseBlock(state, nbt);
|
||||
return new BaseBlock(state, nbt).toImmutableState();
|
||||
}
|
||||
}
|
||||
return state;
|
||||
@ -297,10 +299,10 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, index++) {
|
||||
BlockState block = getBlock(index);
|
||||
switch (block.getBlockType()) {
|
||||
case AIR:
|
||||
case CAVE_AIR:
|
||||
case VOID_AIR:
|
||||
switch (block.getBlockType().getResource().toUpperCase()) {
|
||||
case "AIR":
|
||||
case "CAVE_AIR":
|
||||
case "VOID_AIR":
|
||||
continue;
|
||||
default:
|
||||
task.run(x, y, z, block);
|
||||
|
@ -2,6 +2,7 @@ package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
@ -44,8 +45,8 @@ public class EmptyExtent implements Extent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getFullBlock(BlockVector3 position) {
|
||||
return EditSession.nullBlock;
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return EditSession.nullBlock.toBaseBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -123,12 +123,12 @@ public class FastWorldEditExtent extends AbstractDelegateExtent implements HasFa
|
||||
@Override
|
||||
public BlockState getLazyBlock(int x, int y, int z) {
|
||||
int combinedId4Data = queue.getCombinedId4Data(x, y, z, 0);
|
||||
BlockTypes type = BlockTypes.getFromStateId(combinedId4Data);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId4Data);
|
||||
BlockState state = type.withStateId(combinedId4Data);
|
||||
if (type.getMaterial().hasContainer()) {
|
||||
CompoundTag tile = queue.getTileEntity(x, y, z);
|
||||
if (tile != null) {
|
||||
return new BaseBlock(state, tile);
|
||||
return new BaseBlock(state, tile).toImmutableState();
|
||||
}
|
||||
}
|
||||
return state;
|
||||
|
@ -53,12 +53,12 @@ public class NullExtent extends FaweRegionExtent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getBlock(final BlockVector3 arg0) {
|
||||
public BlockState getBlock(final BlockVector3 arg0) {
|
||||
throw new FaweException(reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getLazyBlock(final BlockVector3 arg0) {
|
||||
public BlockState getLazyBlock(final BlockVector3 arg0) {
|
||||
throw new FaweException(reason);
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ public class NullExtent extends FaweRegionExtent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getLazyBlock(int x, int y, int z) {
|
||||
public BlockState getLazyBlock(int x, int y, int z) {
|
||||
throw new FaweException(reason);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.boydti.fawe.object.extent;
|
||||
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
|
||||
@ -80,17 +81,22 @@ public class TransformExtent extends BlockTransformExtent {
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(int x, int y, int z) {
|
||||
return transformFast(super.getLazyBlock(getPos(x, y, z)));
|
||||
return transformFast(super.getLazyBlock(getPos(x, y, z))).toImmutableState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(BlockVector3 position) {
|
||||
return transformFast(super.getLazyBlock(getPos(position)));
|
||||
return transformFast(super.getLazyBlock(getPos(position))).toImmutableState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
return transformFast(super.getBlock(getPos(position)));
|
||||
return transformFast(super.getBlock(getPos(position))).toImmutableState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return transformFast(super.getFullBlock(getPos(position)).toImmutableState());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -102,14 +108,14 @@ public class TransformExtent extends BlockTransformExtent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException {
|
||||
return super.setBlock(getPos(x, y, z), transformFastInverse((BlockState) block));
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) throws WorldEditException {
|
||||
return super.setBlock(getPos(x, y, z), transformFastInverse((BlockState)block));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean setBlock(BlockVector3 location, BlockStateHolder block) throws WorldEditException {
|
||||
return super.setBlock(getPos(location), transformFastInverse((BlockState) block));
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
|
||||
return super.setBlock(getPos(location), transformFastInverse((BlockState)block));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.boydti.fawe.object.pattern;
|
||||
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
@ -97,8 +97,8 @@ public class PatternExtent extends AbstractPattern implements Extent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getFullBlock(BlockVector3 position) {
|
||||
return getBlock(position);
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return getBlock(position).toBaseBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -62,7 +62,7 @@ public class PropertyPattern extends AbstractExtentPattern {
|
||||
}
|
||||
}
|
||||
|
||||
private void add(BlockTypes type, PropertyKey key, Operator operator, MutableCharSequence value, boolean wrap) {
|
||||
private void add(BlockType type, PropertyKey key, Operator operator, MutableCharSequence value, boolean wrap) {
|
||||
if (!type.hasProperty(key)) return;
|
||||
AbstractProperty property = (AbstractProperty) type.getProperty(key);
|
||||
BlockState defaultState = type.getDefaultState();
|
||||
@ -129,14 +129,14 @@ public class PropertyPattern extends AbstractExtentPattern {
|
||||
charSequence.setString(input);
|
||||
charSequence.setSubstring(0, propStart);
|
||||
|
||||
BlockTypes type = null;
|
||||
List<BlockTypes> blockTypeList = null;
|
||||
BlockType type = null;
|
||||
List<BlockType> blockTypeList = null;
|
||||
if (StringMan.isAlphanumericUnd(charSequence)) {
|
||||
type = BlockTypes.get(charSequence);
|
||||
} else {
|
||||
String regex = charSequence.toString();
|
||||
blockTypeList = new ArrayList<>();
|
||||
for (BlockTypes myType : BlockTypes.values) {
|
||||
for (BlockType myType : BlockTypes.values) {
|
||||
if (myType.getId().matches(regex)) {
|
||||
blockTypeList.add(myType);
|
||||
}
|
||||
@ -164,7 +164,7 @@ public class PropertyPattern extends AbstractExtentPattern {
|
||||
char firstChar = input.charAt(last + 1);
|
||||
if (type != null) add(type, key, operator, charSequence, wrap);
|
||||
else {
|
||||
for (BlockTypes myType : blockTypeList) {
|
||||
for (BlockType myType : blockTypeList) {
|
||||
add(myType, key, operator, charSequence, wrap);
|
||||
}
|
||||
}
|
||||
@ -203,7 +203,7 @@ public class PropertyPattern extends AbstractExtentPattern {
|
||||
if (newOrdinal != ordinal) {
|
||||
CompoundTag nbt = block.getNbtData();
|
||||
BlockState newState = BlockState.getFromOrdinal(newOrdinal);
|
||||
return nbt != null ? new BaseBlock(newState, nbt) : newState;
|
||||
return nbt != null ? new BaseBlock(newState, nbt).toImmutableState() : newState;
|
||||
}
|
||||
return orDefault;
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import com.boydti.fawe.FaweCache;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||
import com.sk89q.worldedit.function.pattern.AbstractPattern;
|
||||
|
@ -178,14 +178,9 @@ public class StructureFormat implements ClipboardReader, ClipboardWriter {
|
||||
for (BlockVector3 point : region) {
|
||||
BlockStateHolder block = clipboard.getBlock(point);
|
||||
int combined = block.getInternalId();
|
||||
BlockTypes type = block.getBlockType();
|
||||
BlockType type = block.getBlockType();
|
||||
|
||||
switch (type) {
|
||||
case STRUCTURE_VOID:
|
||||
continue;
|
||||
default:
|
||||
}
|
||||
if (indexes.containsKey(combined)) {
|
||||
if (type == BlockTypes.STRUCTURE_VOID || indexes.containsKey(combined)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -194,7 +189,7 @@ public class StructureFormat implements ClipboardReader, ClipboardWriter {
|
||||
paletteEntry.put("Name", type.getId());
|
||||
if (block.getInternalId() != type.getInternalId()) {
|
||||
Map<String, Object> properties = null;
|
||||
for (AbstractProperty property : (List<AbstractProperty>) type.getProperties()) {
|
||||
for (AbstractProperty property : (List<AbstractProperty<?>>) type.getProperties()) {
|
||||
int propIndex = property.getIndex(block.getInternalId());
|
||||
if (propIndex != 0) {
|
||||
if (properties == null) properties = new HashMap<>();
|
||||
@ -218,8 +213,8 @@ public class StructureFormat implements ClipboardReader, ClipboardWriter {
|
||||
BlockVector3 min = region.getMinimumPoint();
|
||||
for (BlockVector3 point : region) {
|
||||
BlockStateHolder block = clipboard.getBlock(point);
|
||||
switch (block.getBlockType()) {
|
||||
case STRUCTURE_VOID:
|
||||
switch (block.getBlockType().getResource().toUpperCase()) {
|
||||
case "STRUCTURE_VOID":
|
||||
continue;
|
||||
default:
|
||||
int combined = block.getInternalId();
|
||||
|
@ -23,6 +23,7 @@ import com.sk89q.worldedit.event.platform.InputType;
|
||||
import com.sk89q.worldedit.event.platform.PlayerInputEvent;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
@ -128,7 +129,7 @@ public class SchemVis extends ImmutableVirtualWorld {
|
||||
|
||||
File file = new File(cachedFile.getParentFile(), filename.substring(1, filename.length() - 7));
|
||||
URI uri = file.toURI();
|
||||
ClipboardFormat format = ClipboardFormat.findByFile(file);
|
||||
ClipboardFormat format = ClipboardFormats.findByFile(file);
|
||||
format.hold(player, uri, new FileInputStream(file));
|
||||
BBC.SCHEMATIC_LOADED.send(player, filename);
|
||||
session.setVirtualWorld(null);
|
||||
@ -144,7 +145,7 @@ public class SchemVis extends ImmutableVirtualWorld {
|
||||
|
||||
File file = new File(clicked.getParentFile(), filename.substring(1, filename.length() - 7));
|
||||
URI uri = file.toURI();
|
||||
ClipboardFormat format = ClipboardFormat.findByFile(file);
|
||||
ClipboardFormat format = ClipboardFormats.findByFile(file);
|
||||
|
||||
boolean contains = existing instanceof URIClipboardHolder && ((URIClipboardHolder) existing).contains(uri);
|
||||
if (contains) {
|
||||
@ -386,7 +387,7 @@ public class SchemVis extends ImmutableVirtualWorld {
|
||||
player.sendMessage(BBC.getPrefix() + "Converting: " + file);
|
||||
cached.createNewFile();
|
||||
try (FileInputStream in = new FileInputStream(file)) {
|
||||
ClipboardFormat format = ClipboardFormat.findByFile(file);
|
||||
ClipboardFormat format = ClipboardFormats.findByFile(file);
|
||||
if (format != null) {
|
||||
ClipboardReader reader = format.getReader(in);
|
||||
Clipboard clipboard = reader.read();
|
||||
|
@ -10,9 +10,9 @@ import java.io.FileNotFoundException;
|
||||
|
||||
public class CachedTextureUtil extends DelegateTextureUtil {
|
||||
private final TextureUtil parent;
|
||||
private transient Int2ObjectOpenHashMap<BlockTypes> colorBlockMap;
|
||||
private transient Int2ObjectOpenHashMap<BlockType> colorBlockMap;
|
||||
private transient Int2ObjectOpenHashMap<Integer> colorBiomeMap;
|
||||
private transient Int2ObjectOpenHashMap<BlockTypes[]> colorLayerMap;
|
||||
private transient Int2ObjectOpenHashMap<BlockType[]> colorLayerMap;
|
||||
|
||||
public CachedTextureUtil(TextureUtil parent) throws FileNotFoundException {
|
||||
super(parent);
|
||||
@ -23,8 +23,8 @@ public class CachedTextureUtil extends DelegateTextureUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockTypes[] getNearestLayer(int color) {
|
||||
BlockTypes[] closest = colorLayerMap.get(color);
|
||||
public BlockType[] getNearestLayer(int color) {
|
||||
BlockType[] closest = colorLayerMap.get(color);
|
||||
if (closest != null) {
|
||||
return closest;
|
||||
}
|
||||
@ -49,12 +49,12 @@ public class CachedTextureUtil extends DelegateTextureUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockTypes getNearestBlock(int color) {
|
||||
BlockTypes value = colorBlockMap.get(color);
|
||||
public BlockType getNearestBlock(int color) {
|
||||
BlockType value = colorBlockMap.get(color);
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
BlockTypes result = parent.getNearestBlock(color);
|
||||
BlockType result = parent.getNearestBlock(color);
|
||||
if (result != null) {
|
||||
colorBlockMap.put((int) color, result);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public class DelegateTextureUtil extends TextureUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockTypes getNearestBlock(int color) {
|
||||
public BlockType getNearestBlock(int color) {
|
||||
return parent.getNearestBlock(color);
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ public class DelegateTextureUtil extends TextureUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockTypes[] getNearestLayer(int color) {
|
||||
public BlockType[] getNearestLayer(int color) {
|
||||
return parent.getNearestLayer(color);
|
||||
}
|
||||
|
||||
|
@ -26,14 +26,14 @@ public class FilteredTextureUtil extends TextureUtil {
|
||||
this.validBlockIds = new int[distances.length];
|
||||
int num = 0;
|
||||
for (int i = 0; i < parent.validBlockIds.length; i++) {
|
||||
BlockTypes block = BlockTypes.get(parent.validBlockIds[i]);
|
||||
BlockType block = BlockTypes.get(parent.validBlockIds[i]);
|
||||
if (blocks.contains(block)) num++;
|
||||
}
|
||||
this.validBlockIds = new int[num];
|
||||
this.validColors = new int[num];
|
||||
num = 0;
|
||||
for (int i = 0; i < parent.validBlockIds.length; i++) {
|
||||
BlockTypes block = BlockTypes.get(parent.validBlockIds[i]);
|
||||
BlockType block = BlockTypes.get(parent.validBlockIds[i]);
|
||||
if (blocks.contains(block)) {
|
||||
validBlockIds[num] = parent.validBlockIds[i];
|
||||
validColors[num++] = parent.validColors[i];
|
||||
|
@ -12,6 +12,7 @@ import com.github.luben.zstd.ZstdOutputStream;
|
||||
import com.sk89q.jnbt.*;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import java.awt.Graphics2D;
|
||||
@ -889,7 +890,7 @@ public class MainUtil {
|
||||
public static File resolve(File dir, String filename, @Nullable ClipboardFormat format, boolean allowDir) {
|
||||
if (format != null) {
|
||||
if (!filename.matches(".*\\.[\\w].*")) {
|
||||
filename = filename + "." + format.getExtension();
|
||||
filename = filename + "." + format.getPrimaryFileExtension();
|
||||
}
|
||||
return MainUtil.resolveRelative(new File(dir, filename));
|
||||
}
|
||||
@ -897,8 +898,8 @@ public class MainUtil {
|
||||
File file = MainUtil.resolveRelative(new File(dir, filename));
|
||||
if (file.exists() && file.isDirectory()) return file;
|
||||
}
|
||||
for (ClipboardFormat f : ClipboardFormat.values) {
|
||||
File file = MainUtil.resolveRelative(new File(dir, filename + "." + f.getExtension()));
|
||||
for (ClipboardFormat f : ClipboardFormats.getAll()) {
|
||||
File file = MainUtil.resolveRelative(new File(dir, filename + "." + f.getPrimaryFileExtension()));
|
||||
if (file.exists()) return file;
|
||||
}
|
||||
return null;
|
||||
|
@ -79,14 +79,14 @@ public class RandomTextureUtil extends CachedTextureUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockTypes getNearestBlock(int color) {
|
||||
public BlockType getNearestBlock(int color) {
|
||||
int offsetColor = offsets.getOrDefault(color, 0);
|
||||
if (offsetColor != 0) {
|
||||
offsetColor = addRandomColor(color, offsetColor);
|
||||
} else {
|
||||
offsetColor = color;
|
||||
}
|
||||
BlockTypes res = super.getNearestBlock(offsetColor);
|
||||
BlockType res = super.getNearestBlock(offsetColor);
|
||||
if (res == null) return null;
|
||||
int newColor = getColor(res);
|
||||
{
|
||||
|
@ -372,7 +372,7 @@ public class TextureUtil implements TextureHolder{
|
||||
}
|
||||
}
|
||||
|
||||
public BlockTypes getNearestBlock(int color) {
|
||||
public BlockType getNearestBlock(int color) {
|
||||
long min = Long.MAX_VALUE;
|
||||
int closest = 0;
|
||||
int red1 = (color >> 16) & 0xFF;
|
||||
@ -420,7 +420,7 @@ public class TextureUtil implements TextureHolder{
|
||||
return BlockTypes.get(closest);
|
||||
}
|
||||
|
||||
private BlockTypes[] layerBuffer = new BlockTypes[2];
|
||||
private BlockType[] layerBuffer = new BlockType[2];
|
||||
|
||||
/**
|
||||
* Returns the block combined ids as an array
|
||||
@ -428,7 +428,7 @@ public class TextureUtil implements TextureHolder{
|
||||
* @param color
|
||||
* @return
|
||||
*/
|
||||
public BlockTypes[] getNearestLayer(int color) {
|
||||
public BlockType[] getNearestLayer(int color) {
|
||||
int[] closest = null;
|
||||
long min = Long.MAX_VALUE;
|
||||
int red1 = (color >> 16) & 0xFF;
|
||||
|
@ -6,9 +6,9 @@ import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.util.EditSessionBuilder;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.AbstractPlayerActor;
|
||||
@ -51,7 +51,7 @@ public class PlayerWrapper extends AbstractPlayerActor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockInHand(HandSide handSide) throws WorldEditException {
|
||||
public BaseBlock getBlockInHand(HandSide handSide) throws WorldEditException {
|
||||
return parent.getBlockInHand(handSide);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.world.AbstractWorld;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
@ -240,7 +241,7 @@ public class WorldWrapper extends AbstractWorld {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getFullBlock(BlockVector3 position) {
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return parent.getFullBlock(position);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ import com.sk89q.worldedit.command.SchematicCommands;
|
||||
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.BuiltInClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
@ -149,7 +150,7 @@ public class CuboidClipboard {
|
||||
}
|
||||
|
||||
private BaseBlock adapt(BlockState state) {
|
||||
if (state instanceof BaseBlock) return (BaseBlock) state;
|
||||
// if (state instanceof BaseBlock) return (BaseBlock) state;
|
||||
return new BaseBlock(state);
|
||||
}
|
||||
|
||||
@ -173,7 +174,7 @@ public class CuboidClipboard {
|
||||
}
|
||||
|
||||
public boolean setBlock(int x, int y, int z, BaseBlock block) {
|
||||
return setBlock(x, y, z, (BlockState) block);
|
||||
return setBlock(x, y, z, block.toImmutableState());
|
||||
}
|
||||
|
||||
public boolean setBlock(int x, int y, int z, BlockState block) {
|
||||
@ -270,7 +271,7 @@ public class CuboidClipboard {
|
||||
if (region.contains(pt)) {
|
||||
setBlock(x, y, z, editSession.getBlock(pt));
|
||||
} else {
|
||||
setBlock(x, y, z, null);
|
||||
setBlock(x, y, z, (BlockState)null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -435,7 +436,7 @@ public class CuboidClipboard {
|
||||
Operations.completeLegacy(result.copyTo(target));
|
||||
this.clipboard = target;
|
||||
}
|
||||
new Schematic(clipboard).save(path, ClipboardFormat.SPONGE_SCHEMATIC);
|
||||
new Schematic(clipboard).save(path, BuiltInClipboardFormat.SPONGE_SCHEMATIC);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -450,7 +451,7 @@ public class CuboidClipboard {
|
||||
@Deprecated
|
||||
public static CuboidClipboard loadSchematic(File path) throws DataException, IOException {
|
||||
checkNotNull(path);
|
||||
return new CuboidClipboard((BlockVector3) ClipboardFormat.SCHEMATIC.load(path).getClipboard());
|
||||
return new CuboidClipboard((BlockVector3) BuiltInClipboardFormat.MCEDIT_SCHEMATIC.load(path).getClipboard());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -981,7 +981,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getFullBlock(BlockVector3 position) {
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return world.getFullBlock(position);
|
||||
}
|
||||
|
||||
@ -1094,12 +1094,12 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
||||
}
|
||||
@Deprecated
|
||||
public boolean setBlock(int x, int y, int z, BaseBlock block) {
|
||||
return setBlock(x, y, z, (BlockState) block);
|
||||
return setBlock(x, y, z, block.toImmutableState());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean setBlock(BlockVector3 position, BaseBlock block) throws MaxChangedBlocksException {
|
||||
return setBlock(position, (BlockState) block);
|
||||
return setBlock(position, block.toImmutableState());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@ -2502,16 +2502,16 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
||||
}
|
||||
for (int y = maxY; y >= 1; --y) {
|
||||
final BlockType type = getBlockType(x, y, z);
|
||||
switch (type.getTypeEnum()) {
|
||||
case ICE:
|
||||
switch (type.getResource().toUpperCase()) {
|
||||
case "ICE":
|
||||
this.setBlock(x, y, z, BlockTypes.WATER.getDefaultState());
|
||||
break;
|
||||
case SNOW:
|
||||
case "SNOW":
|
||||
this.setBlock(x, y, z, BlockTypes.AIR.getDefaultState());
|
||||
break;
|
||||
case CAVE_AIR:
|
||||
case VOID_AIR:
|
||||
case AIR:
|
||||
case "CAVE_AIR":
|
||||
case "VOID_AIR":
|
||||
case "AIR":
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
@ -2574,20 +2574,20 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
||||
outer:
|
||||
for (int y = maxY; y >= 1; --y) {
|
||||
BlockType type = getBlockType(x, y, z);
|
||||
switch (type.getTypeEnum()) {
|
||||
case AIR:
|
||||
case CAVE_AIR:
|
||||
case VOID_AIR:
|
||||
switch (type.getResource().toUpperCase()) {
|
||||
case "AIR":
|
||||
case "CAVE_AIR":
|
||||
case "VOID_AIR":
|
||||
continue;
|
||||
case WATER:
|
||||
case "WATER":
|
||||
this.setBlock(x, y, z, BlockTypes.ICE.getDefaultState());
|
||||
break outer;
|
||||
case ACACIA_LEAVES: // TODO FIXME get leaves dynamically
|
||||
case BIRCH_LEAVES:
|
||||
case DARK_OAK_LEAVES:
|
||||
case JUNGLE_LEAVES:
|
||||
case OAK_LEAVES:
|
||||
case SPRUCE_LEAVES:
|
||||
case "ACACIA_LEAVES": // TODO FIXME get leaves dynamically
|
||||
case "BIRCH_LEAVES":
|
||||
case "DARK_OAK_LEAVES":
|
||||
case "JUNGLE_LEAVES":
|
||||
case "OAK_LEAVES":
|
||||
case "SPRUCE_LEAVES":
|
||||
// int ceilRadius = (int) Math.ceil(radius);
|
||||
// for (int x = ox - ceilRadius; x <= ox + ceilRadius; ++x) {
|
||||
// for (int z = oz - ceilRadius; z <= oz + ceilRadius; ++z) {
|
||||
@ -2670,12 +2670,12 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
||||
loop:
|
||||
for (int y = maxY; y >= 1; --y) {
|
||||
BlockType block = getBlockType(x, y, z);
|
||||
switch (block.getTypeEnum()) {
|
||||
case DIRT:
|
||||
switch (block.getResource().toUpperCase()) {
|
||||
case "DIRT":
|
||||
this.setBlock(x, y, z, BlockTypes.GRASS_BLOCK.getDefaultState());
|
||||
break loop;
|
||||
case WATER:
|
||||
case LAVA:
|
||||
case "WATER":
|
||||
case "LAVA":
|
||||
break loop;
|
||||
default:
|
||||
if (block.getMaterial().isMovementBlocker()) {
|
||||
@ -2770,18 +2770,18 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
||||
this.changes++;
|
||||
for (int y = basePosition.getBlockY(); y >= (basePosition.getBlockY() - 10); --y) {
|
||||
BlockType type = getBlockType(x, y, z);
|
||||
switch (type.getTypeEnum()) {
|
||||
case GRASS:
|
||||
case DIRT:
|
||||
switch (type.getResource().toUpperCase()) {
|
||||
case "GRASS":
|
||||
case "DIRT":
|
||||
treeType.generate(this, BlockVector3.at(x, y + 1, z));
|
||||
this.changes++;
|
||||
break;
|
||||
case SNOW:
|
||||
case "SNOW":
|
||||
setBlock(BlockVector3.at(x, y, z), BlockTypes.AIR.getDefaultState());
|
||||
break;
|
||||
case AIR:
|
||||
case CAVE_AIR:
|
||||
case VOID_AIR:
|
||||
case "AIR":
|
||||
case "CAVE_AIR":
|
||||
case "VOID_AIR":
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
|
@ -22,6 +22,7 @@ package com.sk89q.worldedit;
|
||||
import com.sk89q.worldedit.util.logging.LogFormat;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
|
||||
@ -53,7 +54,7 @@ public abstract class LocalConfiguration {
|
||||
public String logFile = "";
|
||||
public String logFormat = LogFormat.DEFAULT_FORMAT;
|
||||
public boolean registerHelp = true; // what is the point of this, it's not even used
|
||||
public ItemTypes wandItem = ItemTypes.WOODEN_AXE;
|
||||
public String wandItem = ItemTypes.WOODEN_AXE.getId();
|
||||
public boolean superPickaxeDrop = true;
|
||||
public boolean superPickaxeManyDrop = true;
|
||||
public boolean noDoubleSlash = false;
|
||||
@ -61,7 +62,7 @@ public abstract class LocalConfiguration {
|
||||
public boolean useInventoryOverride = false;
|
||||
public boolean useInventoryCreativeOverride = false;
|
||||
public boolean navigationUseGlass = true;
|
||||
public ItemTypes navigationWand = ItemTypes.COMPASS;
|
||||
public String navigationWand = ItemTypes.COMPASS.getId();
|
||||
public int navigationWandMaxDistance = 50;
|
||||
public int scriptTimeout = 3000;
|
||||
public Set<BlockType> allowedDataCycleBlocks = new HashSet<>();
|
||||
|
@ -1030,12 +1030,12 @@ public class LocalSession implements TextureHolder {
|
||||
}
|
||||
|
||||
public void setTool(BaseItem item, @Nullable Tool tool, Player player) throws InvalidToolBindException {
|
||||
ItemTypes type = item.getType();
|
||||
ItemType type = item.getType();
|
||||
if (type.hasBlockType() && type.getBlockType().getMaterial().isAir()) {
|
||||
throw new InvalidToolBindException(type, "Blocks can't be used");
|
||||
} else if (type == config.wandItem) {
|
||||
} else if (type.getId().equalsIgnoreCase(config.wandItem)) {
|
||||
throw new InvalidToolBindException(type, "Already used for the wand");
|
||||
} else if (type == config.navigationWand) {
|
||||
} else if (type.getId().equalsIgnoreCase(config.navigationWand)) {
|
||||
throw new InvalidToolBindException(type, "Already used for the navigation wand");
|
||||
}
|
||||
Tool previous;
|
||||
|
@ -69,8 +69,8 @@ public class BaseItem implements NbtValued {
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public ItemTypes getType() {
|
||||
return (ItemTypes) this.itemType;
|
||||
public ItemType getType() {
|
||||
return this.itemType;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,220 +0,0 @@
|
||||
/*
|
||||
* 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.blocks;
|
||||
|
||||
import com.sk89q.worldedit.registry.state.PropertyGroup;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Block types.
|
||||
*
|
||||
* {@deprecated Please use {@link com.sk89q.worldedit.world.block.BlockType }}
|
||||
*/
|
||||
@Deprecated
|
||||
public class BlockType {
|
||||
|
||||
public static double centralTopLimit(com.sk89q.worldedit.world.block.BlockType type) {
|
||||
checkNotNull(type);
|
||||
return centralTopLimit(type.getDefaultState());
|
||||
}
|
||||
|
||||
public static double centralBottomLimit(BlockStateHolder block) {
|
||||
checkNotNull(block);
|
||||
BlockTypes type = block.getBlockType();
|
||||
switch (type) {
|
||||
case CREEPER_WALL_HEAD:
|
||||
case DRAGON_WALL_HEAD:
|
||||
case PLAYER_WALL_HEAD:
|
||||
case ZOMBIE_WALL_HEAD: return 0.25;
|
||||
case ACACIA_SLAB:
|
||||
case BIRCH_SLAB:
|
||||
case BRICK_SLAB:
|
||||
case COBBLESTONE_SLAB:
|
||||
case DARK_OAK_SLAB:
|
||||
case DARK_PRISMARINE_SLAB:
|
||||
case JUNGLE_SLAB:
|
||||
case NETHER_BRICK_SLAB:
|
||||
case OAK_SLAB:
|
||||
case PETRIFIED_OAK_SLAB:
|
||||
case PRISMARINE_BRICK_SLAB:
|
||||
case PRISMARINE_SLAB:
|
||||
case PURPUR_SLAB:
|
||||
case QUARTZ_SLAB:
|
||||
case RED_SANDSTONE_SLAB:
|
||||
case SANDSTONE_SLAB:
|
||||
case SPRUCE_SLAB:
|
||||
case STONE_BRICK_SLAB:
|
||||
case STONE_SLAB: {
|
||||
String state = (String) block.getState(PropertyKey.TYPE);
|
||||
if (state == null) return 0;
|
||||
switch (state) {
|
||||
case "double":
|
||||
case "bottom":
|
||||
return 0;
|
||||
case "top":
|
||||
return 0.5;
|
||||
}
|
||||
}
|
||||
case ACACIA_TRAPDOOR:
|
||||
case BIRCH_TRAPDOOR:
|
||||
case DARK_OAK_TRAPDOOR:
|
||||
case IRON_TRAPDOOR:
|
||||
case JUNGLE_TRAPDOOR:
|
||||
case OAK_TRAPDOOR:
|
||||
case SPRUCE_TRAPDOOR:
|
||||
if (block.getState(PropertyKey.OPEN) == Boolean.TRUE) {
|
||||
return 1;
|
||||
} else if ("bottom".equals(block.getState(PropertyKey.HALF))) {
|
||||
return 0.8125;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
case ACACIA_FENCE_GATE:
|
||||
case BIRCH_FENCE_GATE:
|
||||
case DARK_OAK_FENCE_GATE:
|
||||
case JUNGLE_FENCE_GATE:
|
||||
case OAK_FENCE_GATE:
|
||||
case SPRUCE_FENCE_GATE: return block.getState(PropertyKey.OPEN) == Boolean.TRUE ? 1 : 0;
|
||||
default:
|
||||
if (type.getMaterial().isMovementBlocker()) return 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the y offset a player falls to when falling onto the top of a block at xp+0.5/zp+0.5.
|
||||
*
|
||||
* @param block the block
|
||||
* @return the y offset
|
||||
*/
|
||||
public static double centralTopLimit(BlockStateHolder block) {
|
||||
checkNotNull(block);
|
||||
BlockTypes type = block.getBlockType();
|
||||
switch (type) {
|
||||
case BLACK_BED:
|
||||
case BLUE_BED:
|
||||
case BROWN_BED:
|
||||
case CYAN_BED:
|
||||
case GRAY_BED:
|
||||
case GREEN_BED:
|
||||
case LIGHT_BLUE_BED:
|
||||
case LIGHT_GRAY_BED:
|
||||
case LIME_BED:
|
||||
case MAGENTA_BED:
|
||||
case ORANGE_BED:
|
||||
case PINK_BED:
|
||||
case PURPLE_BED:
|
||||
case RED_BED:
|
||||
case WHITE_BED:
|
||||
case YELLOW_BED: return 0.5625;
|
||||
case BREWING_STAND: return 0.875;
|
||||
case CAKE: return (block.getState(PropertyKey.BITES) == (Integer) 6) ? 0 : 0.4375;
|
||||
case CAULDRON: return 0.3125;
|
||||
case COCOA: return 0.750;
|
||||
case ENCHANTING_TABLE: return 0.75;
|
||||
case END_PORTAL_FRAME: return block.getState(PropertyKey.EYE) == Boolean.TRUE ? 1 : 0.8125;
|
||||
case CREEPER_HEAD:
|
||||
case DRAGON_HEAD:
|
||||
case PISTON_HEAD:
|
||||
case PLAYER_HEAD:
|
||||
case ZOMBIE_HEAD: return 0.5;
|
||||
case CREEPER_WALL_HEAD:
|
||||
case DRAGON_WALL_HEAD:
|
||||
case PLAYER_WALL_HEAD:
|
||||
case ZOMBIE_WALL_HEAD: return 0.75;
|
||||
case ACACIA_FENCE:
|
||||
case BIRCH_FENCE:
|
||||
case DARK_OAK_FENCE:
|
||||
case JUNGLE_FENCE:
|
||||
case NETHER_BRICK_FENCE:
|
||||
case OAK_FENCE:
|
||||
case SPRUCE_FENCE: return 1.5;
|
||||
case ACACIA_SLAB:
|
||||
case BIRCH_SLAB:
|
||||
case BRICK_SLAB:
|
||||
case COBBLESTONE_SLAB:
|
||||
case DARK_OAK_SLAB:
|
||||
case DARK_PRISMARINE_SLAB:
|
||||
case JUNGLE_SLAB:
|
||||
case NETHER_BRICK_SLAB:
|
||||
case OAK_SLAB:
|
||||
case PETRIFIED_OAK_SLAB:
|
||||
case PRISMARINE_BRICK_SLAB:
|
||||
case PRISMARINE_SLAB:
|
||||
case PURPUR_SLAB:
|
||||
case QUARTZ_SLAB:
|
||||
case RED_SANDSTONE_SLAB:
|
||||
case SANDSTONE_SLAB:
|
||||
case SPRUCE_SLAB:
|
||||
case STONE_BRICK_SLAB:
|
||||
case STONE_SLAB: {
|
||||
String state = (String) block.getState(PropertyKey.TYPE);
|
||||
if (state == null) return 0.5;
|
||||
switch (state) {
|
||||
case "bottom":
|
||||
return 0.5;
|
||||
case "top":
|
||||
case "double":
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
case LILY_PAD: return 0.015625;
|
||||
case REPEATER: return 0.125;
|
||||
case SOUL_SAND: return 0.875;
|
||||
case COBBLESTONE_WALL:
|
||||
case MOSSY_COBBLESTONE_WALL: return 1.5;
|
||||
case FLOWER_POT: return 0.375;
|
||||
case COMPARATOR: return 0.125;
|
||||
case DAYLIGHT_DETECTOR: return 0.375;
|
||||
case HOPPER: return 0.625;
|
||||
case ACACIA_TRAPDOOR:
|
||||
case BIRCH_TRAPDOOR:
|
||||
case DARK_OAK_TRAPDOOR:
|
||||
case IRON_TRAPDOOR:
|
||||
case JUNGLE_TRAPDOOR:
|
||||
case OAK_TRAPDOOR:
|
||||
case SPRUCE_TRAPDOOR:
|
||||
if (block.getState(PropertyKey.OPEN) == Boolean.TRUE) {
|
||||
return 0;
|
||||
} else if ("top".equals(block.getState(PropertyKey.HALF))) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0.1875;
|
||||
}
|
||||
case ACACIA_FENCE_GATE:
|
||||
case BIRCH_FENCE_GATE:
|
||||
case DARK_OAK_FENCE_GATE:
|
||||
case JUNGLE_FENCE_GATE:
|
||||
case OAK_FENCE_GATE:
|
||||
case SPRUCE_FENCE_GATE: return block.getState(PropertyKey.OPEN) == Boolean.TRUE ? 0 : 1.5;
|
||||
default:
|
||||
if (type.hasProperty(PropertyKey.LAYERS)) {
|
||||
return PropertyGroup.LEVEL.get(block) * 0.0625;
|
||||
}
|
||||
if (!type.getMaterial().isMovementBlocker()) return 0;
|
||||
return 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -57,6 +57,7 @@ import com.sk89q.worldedit.entity.Player;
|
||||
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.extent.clipboard.io.ClipboardFormats;
|
||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.SingleBlockTypeMask;
|
||||
@ -469,7 +470,7 @@ public class BrushCommands extends BrushProcessor {
|
||||
|
||||
|
||||
try {
|
||||
MultiClipboardHolder clipboards = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, clipboard, null, true);
|
||||
MultiClipboardHolder clipboards = ClipboardFormats.loadAllFromInput(player, clipboard, null, true);
|
||||
if (clipboards == null) {
|
||||
BBC.SCHEMATIC_NOT_FOUND.send(player, clipboard);
|
||||
return null;
|
||||
|
@ -55,7 +55,9 @@ import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.event.extent.PasteEvent;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
||||
import com.sk89q.worldedit.function.block.BlockReplace;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
@ -296,7 +298,7 @@ public class ClipboardCommands extends MethodCommands {
|
||||
@Deprecated
|
||||
@CommandPermissions({"worldedit.clipboard.download"})
|
||||
public void download(final Player player, final LocalSession session, @Optional("schematic") final String formatName) throws CommandException, WorldEditException {
|
||||
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
||||
final ClipboardFormat format = ClipboardFormats.findByAlias(formatName);
|
||||
if (format == null) {
|
||||
BBC.CLIPBOARD_INVALID_FORMAT.send(player, formatName);
|
||||
return;
|
||||
@ -356,8 +358,8 @@ public class ClipboardCommands extends MethodCommands {
|
||||
} else {
|
||||
target = clipboard;
|
||||
}
|
||||
switch (format) {
|
||||
case PNG:
|
||||
switch (format.getName()) {
|
||||
case "PNG":
|
||||
try {
|
||||
FastByteArrayOutputStream baos = new FastByteArrayOutputStream(Short.MAX_VALUE);
|
||||
ClipboardWriter writer = format.getWriter(baos);
|
||||
@ -369,7 +371,7 @@ public class ClipboardCommands extends MethodCommands {
|
||||
url = null;
|
||||
}
|
||||
break;
|
||||
case SCHEMATIC:
|
||||
case "SCHEMATIC":
|
||||
if (Settings.IMP.WEB.URL.isEmpty()) {
|
||||
BBC.SETTING_DISABLE.send(player, "web.url");
|
||||
return;
|
||||
@ -380,30 +382,30 @@ public class ClipboardCommands extends MethodCommands {
|
||||
url = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (url == null) {
|
||||
BBC.GENERATING_LINK_FAILED.send(player);
|
||||
} else {
|
||||
String urlText = url.toString();
|
||||
if (Settings.IMP.WEB.SHORTEN_URLS) {
|
||||
try {
|
||||
urlText = MainUtil.getText("https://empcraft.com/s/?" + URLEncoder.encode(url.toString(), "UTF-8"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (Fawe.imp().getPlatform().equalsIgnoreCase("nukkit")) {
|
||||
FormBuilder form = Fawe.imp().getFormBuilder();
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(player);
|
||||
if (form != null && fp != FakePlayer.getConsole().toFawePlayer()) {
|
||||
form.setTitle("Download Clipboard");
|
||||
form.addInput("url:", urlText, urlText);
|
||||
form.display(fp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
BBC.DOWNLOAD_LINK.send(player, urlText);
|
||||
}
|
||||
if (url == null) {
|
||||
BBC.GENERATING_LINK_FAILED.send(player);
|
||||
} else {
|
||||
String urlText = url.toString();
|
||||
if (Settings.IMP.WEB.SHORTEN_URLS) {
|
||||
try {
|
||||
urlText = MainUtil.getText("https://empcraft.com/s/?" + URLEncoder.encode(url.toString(), "UTF-8"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (Fawe.imp().getPlatform().equalsIgnoreCase("nukkit")) {
|
||||
FormBuilder form = Fawe.imp().getFormBuilder();
|
||||
FawePlayer<Object> fp = FawePlayer.wrap(player);
|
||||
if (form != null && fp != FakePlayer.getConsole().toFawePlayer()) {
|
||||
form.setTitle("Download Clipboard");
|
||||
form.addInput("url:", urlText, urlText);
|
||||
form.display(fp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
BBC.DOWNLOAD_LINK.send(player, urlText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -416,7 +418,7 @@ public class ClipboardCommands extends MethodCommands {
|
||||
)
|
||||
@CommandPermissions({"worldedit.clipboard.asset"})
|
||||
public void asset(final Player player, final LocalSession session, String category) throws CommandException, WorldEditException {
|
||||
final ClipboardFormat format = ClipboardFormat.SCHEMATIC;
|
||||
final ClipboardFormat format = BuiltInClipboardFormat.MCEDIT_SCHEMATIC;
|
||||
ClipboardHolder holder = session.getClipboard();
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
final Transform transform = holder.getTransform();
|
||||
@ -430,7 +432,7 @@ public class ClipboardCommands extends MethodCommands {
|
||||
} else {
|
||||
target = clipboard;
|
||||
}
|
||||
BBC.GENERATING_LINK.send(player, format.name());
|
||||
BBC.GENERATING_LINK.send(player, format.getName());
|
||||
if (Settings.IMP.WEB.ASSETS.isEmpty()) {
|
||||
BBC.SETTING_DISABLE.send(player, "web.assets");
|
||||
return;
|
||||
@ -478,7 +480,7 @@ public class ClipboardCommands extends MethodCommands {
|
||||
}
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
Region region = clipboard.getRegion();
|
||||
BlockVector3 to = atOrigin ? clipboard.getOrigin() : session.getPlacementPosition(player);
|
||||
BlockVector3 to = atOrigin ? clipboard.getOrigin() : session.getPlacementPosition(player);
|
||||
checkPaste(player, editSession, to, holder, clipboard);
|
||||
Operation operation = holder
|
||||
.createPaste(editSession)
|
||||
|
@ -187,7 +187,7 @@ public class GeneralCommands {
|
||||
|
||||
int found = 0;
|
||||
|
||||
for (ItemType searchType : ItemTypes.values) {
|
||||
for (ItemType searchType : ItemTypes.values()) {
|
||||
if (found >= 15) {
|
||||
actor.print(BBC.getPrefix() + "Too many results!");
|
||||
break;
|
||||
|
@ -284,7 +284,7 @@ public class OptionsCommands {
|
||||
|
||||
int found = 0;
|
||||
|
||||
for (ItemType searchType : ItemTypes.values) {
|
||||
for (ItemType searchType : ItemTypes.values()) {
|
||||
if (found >= 15) {
|
||||
actor.print(BBC.getPrefix() + "Too many results!");
|
||||
break;
|
||||
|
@ -16,6 +16,7 @@ import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.ClipboardPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
@ -191,7 +192,7 @@ public class PatternCommands extends MethodCommands {
|
||||
clipboards = Collections.singletonList(clipboard);
|
||||
break;
|
||||
default:
|
||||
MultiClipboardHolder multi = ClipboardFormat.SCHEMATIC.loadAllFromInput(player, location, null, true);
|
||||
MultiClipboardHolder multi = ClipboardFormats.loadAllFromInput(player, location, null, true);
|
||||
clipboards = multi != null ? multi.getHolders() : null;
|
||||
break;
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ import com.sk89q.worldedit.event.extent.PlayerSaveClipboardEvent;
|
||||
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.extent.clipboard.io.BuiltInClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
||||
@ -99,13 +100,13 @@ public class SchematicCommands extends MethodCommands {
|
||||
@Deprecated
|
||||
@CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load", "worldedit.schematic.load.web", "worldedit.schematic.load.asset"})
|
||||
public void loadall(final Player player, final LocalSession session, @Optional("schematic") final String formatName, final String filename, @Switch('r') boolean randomRotate) throws FilenameException {
|
||||
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
||||
final ClipboardFormat format = ClipboardFormats.findByAlias(formatName);
|
||||
if (format == null) {
|
||||
BBC.CLIPBOARD_INVALID_FORMAT.send(player, formatName);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
MultiClipboardHolder all = format.loadAllFromInput(player, filename, null, true);
|
||||
MultiClipboardHolder all = ClipboardFormats.loadAllFromInput(player, filename, null, true);
|
||||
if (all != null) {
|
||||
session.addClipboard(all);
|
||||
BBC.SCHEMATIC_LOADED.send(player, filename);
|
||||
@ -192,7 +193,7 @@ public class SchematicCommands extends MethodCommands {
|
||||
@CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load", "worldedit.schematic.load.asset", "worldedit.schematic.load.web", "worldedit.schematic.load.other"})
|
||||
public void load(final Player player, final LocalSession session, @Optional() final String formatName, String filename) throws FilenameException {
|
||||
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
||||
ClipboardFormat format = formatName == null ? null : ClipboardFormat.findByAlias(formatName);
|
||||
ClipboardFormat format = formatName == null ? null : ClipboardFormats.findByAlias(formatName);
|
||||
InputStream in = null;
|
||||
try {
|
||||
URI uri;
|
||||
@ -207,7 +208,7 @@ public class SchematicCommands extends MethodCommands {
|
||||
ReadableByteChannel rbc = Channels.newChannel(url.openStream());
|
||||
in = Channels.newInputStream(rbc);
|
||||
uri = url.toURI();
|
||||
if (format == null) format = ClipboardFormat.SCHEMATIC;
|
||||
if (format == null) format = BuiltInClipboardFormat.MCEDIT_SCHEMATIC;
|
||||
} else {
|
||||
if (!player.hasPermission("worldedit.schematic.load") && !player.hasPermission("worldedit.clipboard.load")) {
|
||||
BBC.NO_PERM.send(player, "worldedit.clipboard.load");
|
||||
@ -235,7 +236,7 @@ public class SchematicCommands extends MethodCommands {
|
||||
}
|
||||
if (format == null && filename.matches(".*\\.[\\w].*")) {
|
||||
String extension = filename.substring(filename.lastIndexOf('.') + 1, filename.length());
|
||||
format = ClipboardFormat.findByExtension(extension);
|
||||
format = ClipboardFormats.findByExtension(extension);
|
||||
}
|
||||
f = MainUtil.resolve(dir, filename, format, false);
|
||||
}
|
||||
@ -250,7 +251,7 @@ public class SchematicCommands extends MethodCommands {
|
||||
return;
|
||||
}
|
||||
if (format == null) {
|
||||
format = ClipboardFormat.findByFile(f);
|
||||
format = ClipboardFormats.findByFile(f);
|
||||
if (format == null) {
|
||||
BBC.CLIPBOARD_INVALID_FORMAT.send(player, f.getName());
|
||||
return;
|
||||
@ -281,7 +282,7 @@ public class SchematicCommands extends MethodCommands {
|
||||
@CommandPermissions({"worldedit.clipboard.save", "worldedit.schematic.save", "worldedit.schematic.save.other"})
|
||||
public void save(final Player player, final LocalSession session, @Optional("schem") final String formatName, String filename, @Switch('g') boolean global) throws CommandException, WorldEditException {
|
||||
final LocalConfiguration config = this.worldEdit.getConfiguration();
|
||||
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
||||
final ClipboardFormat format = ClipboardFormats.findByAlias(formatName);
|
||||
if (format == null) {
|
||||
player.printError("Unknown schematic format: " + formatName);
|
||||
return;
|
||||
@ -298,14 +299,14 @@ public class SchematicCommands extends MethodCommands {
|
||||
filename = filename.substring(3);
|
||||
}
|
||||
}
|
||||
File f = this.worldEdit.getSafeSaveFile(player, dir, filename, format.getExtension(), format.getExtension());
|
||||
if (f.getName().replaceAll("." + format.getExtension(), "").isEmpty()) {
|
||||
File f = this.worldEdit.getSafeSaveFile(player, dir, filename, format.getPrimaryFileExtension(), format.getPrimaryFileExtension());
|
||||
if (f.getName().replaceAll("." + format.getPrimaryFileExtension(), "").isEmpty()) {
|
||||
File directory = f.getParentFile();
|
||||
if (directory.exists()) {
|
||||
int max = MainUtil.getMaxFileId(directory);
|
||||
f = new File(directory, max + "." + format.getExtension());
|
||||
f = new File(directory, max + "." + format.getPrimaryFileExtension());
|
||||
} else {
|
||||
f = new File(directory, "1." + format.getExtension());
|
||||
f = new File(directory, "1." + format.getPrimaryFileExtension());
|
||||
}
|
||||
}
|
||||
final File parent = f.getParentFile();
|
||||
@ -477,9 +478,9 @@ public class SchematicCommands extends MethodCommands {
|
||||
Message m = new Message(BBC.SCHEMATIC_FORMAT).newline();
|
||||
String baseCmd = Commands.getAlias(SchematicCommands.class, "schematic") + " " + Commands.getAlias(SchematicCommands.class, "save");
|
||||
boolean first = true;
|
||||
for (final ClipboardFormat format : ClipboardFormat.values) {
|
||||
for (final ClipboardFormat format : ClipboardFormats.getAll()) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(format.name()).append(": ");
|
||||
builder.append(format.getName()).append(": ");
|
||||
for (final String lookupName : format.getAliases()) {
|
||||
if (!first) {
|
||||
builder.append(", ");
|
||||
@ -487,7 +488,7 @@ public class SchematicCommands extends MethodCommands {
|
||||
builder.append(lookupName);
|
||||
first = false;
|
||||
}
|
||||
String cmd = baseCmd + " " + format.name() + " <filename>";
|
||||
String cmd = baseCmd + " " + format.getName() + " <filename>";
|
||||
m.text(builder).suggestTip(cmd).newline();
|
||||
first = true;
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ import com.sk89q.worldedit.WorldEditException;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits;
|
||||
@ -287,7 +286,7 @@ public class SelectionCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.wand")
|
||||
public void wand(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException {
|
||||
player.giveItem(new BaseItemStack(we.getConfiguration().wandItem, 1));
|
||||
player.giveItem(new BaseItemStack(ItemTypes.parse(we.getConfiguration().wandItem), 1));
|
||||
BBC.SELECTION_WAND.send(player);
|
||||
if (!FawePlayer.wrap(player).hasPermission("fawe.tips"))
|
||||
BBC.TIP_SEL_LIST.or(BBC.TIP_SELECT_CONNECTED, BBC.TIP_SET_POS1, BBC.TIP_FARWAND, BBC.TIP_DISCORD).send(player);
|
||||
|
@ -67,6 +67,7 @@ import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extension.platform.CommandManager;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
@ -903,7 +904,7 @@ public class UtilityCommands extends MethodCommands {
|
||||
}
|
||||
|
||||
if (formatName != null) {
|
||||
final ClipboardFormat cf = ClipboardFormat.findByAlias(formatName);
|
||||
final ClipboardFormat cf = ClipboardFormats.findByAlias(formatName);
|
||||
forEachFile = new DelegateConsumer<File>(forEachFile) {
|
||||
@Override
|
||||
public void accept(File file) {
|
||||
@ -1013,7 +1014,7 @@ public class UtilityCommands extends MethodCommands {
|
||||
dir = root;
|
||||
}
|
||||
|
||||
ClipboardFormat format = ClipboardFormat.findByFile(file);
|
||||
ClipboardFormat format = ClipboardFormats.findByFile(file);
|
||||
URI relative = dir.toURI().relativize(file.toURI());
|
||||
StringBuilder name = new StringBuilder();
|
||||
if (relative.isAbsolute()) {
|
||||
|
@ -132,12 +132,12 @@ public class FloatingTreeRemover implements BlockTool {
|
||||
|
||||
if (visited.add(next)) {
|
||||
BlockState state = world.getBlock(next);
|
||||
BlockTypes type = state.getBlockType();
|
||||
switch (type) {
|
||||
case AIR:
|
||||
case CAVE_AIR:
|
||||
case VOID_AIR:
|
||||
case SNOW:
|
||||
BlockType type = state.getBlockType();
|
||||
switch (type.getResource().toUpperCase()) {
|
||||
case "AIR":
|
||||
case "CAVE_AIR":
|
||||
case "VOID_AIR":
|
||||
case "SNOW":
|
||||
continue;
|
||||
}
|
||||
if (isTreeBlock(state.getBlockType())) {
|
||||
|
@ -75,7 +75,7 @@ public interface Player extends Entity, Actor {
|
||||
*
|
||||
* @return the item id of the item the player is holding
|
||||
*/
|
||||
BlockState getBlockInHand(HandSide handSide) throws WorldEditException;
|
||||
BaseBlock getBlockInHand(HandSide handSide) throws WorldEditException;
|
||||
|
||||
/**
|
||||
* Gives the player an item.
|
||||
|
@ -55,6 +55,7 @@ import com.sk89q.worldedit.util.HandSide;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
|
||||
@ -77,7 +78,7 @@ public class DefaultBlockParser extends InputParser<BlockStateHolder> {
|
||||
private static BlockState getBlockInHand(Actor actor, HandSide handSide) throws InputParseException {
|
||||
if (actor instanceof Player) {
|
||||
try {
|
||||
return ((Player) actor).getBlockInHand(handSide);
|
||||
return ((Player) actor).getBlockInHand(handSide).toImmutableState();
|
||||
} catch (NotABlockException e) {
|
||||
throw new InputParseException("You're not holding a block!");
|
||||
} catch (WorldEditException e) {
|
||||
@ -179,7 +180,7 @@ public class DefaultBlockParser extends InputParser<BlockStateHolder> {
|
||||
} else if (MathMan.isInteger(split[0])) {
|
||||
state = LegacyMapper.getInstance().getBlockFromLegacy(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
|
||||
} else {
|
||||
BlockTypes type = BlockTypes.get(split[0].toLowerCase());
|
||||
BlockType type = BlockTypes.get(split[0].toLowerCase());
|
||||
if (type != null) {
|
||||
state = LegacyMapper.getInstance().getBlockFromLegacy(type.getLegacyCombinedId() >> 4, Integer.parseInt(split[1]));
|
||||
}
|
||||
@ -238,7 +239,7 @@ public class DefaultBlockParser extends InputParser<BlockStateHolder> {
|
||||
state = item.getType().getBlockType().getDefaultState();
|
||||
nbt = item.getNbtData();
|
||||
} else {
|
||||
BlockTypes type = BlockTypes.parse(typeString.toLowerCase());
|
||||
BlockType type = BlockTypes.parse(typeString.toLowerCase());
|
||||
if (type != null) state = type.getDefaultState();
|
||||
if (state == null) {
|
||||
throw new NoMatchException("Does not match a valid block type: '" + input + "'");
|
||||
@ -261,7 +262,7 @@ public class DefaultBlockParser extends InputParser<BlockStateHolder> {
|
||||
}
|
||||
|
||||
// Check if the item is allowed
|
||||
BlockTypes blockType = state.getBlockType();
|
||||
BlockType blockType = state.getBlockType();
|
||||
|
||||
if (context.isRestricted()) {
|
||||
Actor actor = context.requireActor();
|
||||
|
@ -53,7 +53,7 @@ public class DefaultItemParser extends InputParser<BaseItem> {
|
||||
if (type != null) {
|
||||
Integer legacy = LegacyMapper.getInstance().getLegacyCombined(type);
|
||||
if (legacy != null) {
|
||||
ItemTypes newType = LegacyMapper.getInstance().getItemFromLegacy(legacy >> 4, Integer.parseInt(split[1]));
|
||||
ItemType newType = LegacyMapper.getInstance().getItemFromLegacy(legacy >> 4, Integer.parseInt(split[1]));
|
||||
if (newType != null) type = newType;
|
||||
}
|
||||
}
|
||||
|
@ -33,8 +33,9 @@ import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.TargetBlock;
|
||||
import com.sk89q.worldedit.util.auth.AuthorizationException;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypeUtil;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.gamemode.GameMode;
|
||||
@ -125,7 +126,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
|
||||
if (y - 1 != origY) {
|
||||
final BlockVector3 pos = BlockVector3.at(x, y - 2, z);
|
||||
final BlockStateHolder state = world.getBlock(pos);
|
||||
setPosition(Vector3.at(x + 0.5, y - 2 + BlockType.centralTopLimit(state), z + 0.5));
|
||||
setPosition(Vector3.at(x + 0.5, y - 2 + BlockTypeUtil.centralTopLimit(state), z + 0.5));
|
||||
// setPosition(Vector3.at(x + 0.5, y - 2 + 1, z + 0.5));
|
||||
}
|
||||
|
||||
@ -147,7 +148,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
|
||||
final BlockVector3 pos = BlockVector3.at(x, y, z);
|
||||
final BlockState id = world.getBlock(pos);
|
||||
if (id.getBlockType().getMaterial().isMovementBlocker()) {
|
||||
setPosition(Vector3.at(x + 0.5, y + + BlockType.centralTopLimit(id), z + 0.5));
|
||||
setPosition(Vector3.at(x + 0.5, y + + BlockTypeUtil.centralTopLimit(id), z + 0.5));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -182,18 +183,18 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
|
||||
BlockState state;
|
||||
if (level >= maxY) state = BlockTypes.VOID_AIR.getDefaultState();
|
||||
else state = world.getBlock(BlockVector3.at(x, level, z));
|
||||
BlockTypes type = state.getBlockType();
|
||||
BlockType type = state.getBlockType();
|
||||
BlockMaterial material = type.getMaterial();
|
||||
|
||||
if (!material.isFullCube() || !material.isMovementBlocker()) {
|
||||
if (!lastState) {
|
||||
lastState = BlockType.centralBottomLimit(state) != 1;
|
||||
lastState = BlockTypeUtil.centralBottomLimit(state) != 1;
|
||||
continue;
|
||||
}
|
||||
if (freeStart == -1) {
|
||||
freeStart = level + BlockType.centralTopLimit(state);
|
||||
freeStart = level + BlockTypeUtil.centralTopLimit(state);
|
||||
} else {
|
||||
double bottomLimit = BlockType.centralBottomLimit(state);
|
||||
double bottomLimit = BlockTypeUtil.centralBottomLimit(state);
|
||||
double space = level + bottomLimit - freeStart;
|
||||
if (space >= height) {
|
||||
setPosition(Vector3.at(x + 0.5, freeStart, z + 0.5));
|
||||
@ -234,18 +235,18 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
|
||||
BlockState state;
|
||||
if (level >= maxY) state = BlockTypes.VOID_AIR.getDefaultState();
|
||||
else state = world.getBlock(BlockVector3.at(x, level, z));
|
||||
BlockTypes type = state.getBlockType();
|
||||
BlockType type = state.getBlockType();
|
||||
BlockMaterial material = type.getMaterial();
|
||||
|
||||
if (!material.isFullCube() || !material.isMovementBlocker()) {
|
||||
if (!lastState) {
|
||||
lastState = BlockType.centralTopLimit(state) != 0;
|
||||
lastState = BlockTypeUtil.centralTopLimit(state) != 0;
|
||||
continue;
|
||||
}
|
||||
if (freeEnd == -1) {
|
||||
freeEnd = level + BlockType.centralBottomLimit(state);
|
||||
freeEnd = level + BlockTypeUtil.centralBottomLimit(state);
|
||||
} else {
|
||||
double topLimit = BlockType.centralTopLimit(state);
|
||||
double topLimit = BlockTypeUtil.centralTopLimit(state);
|
||||
double freeStart = level + topLimit;
|
||||
double space = freeEnd - freeStart;
|
||||
if (space >= height) {
|
||||
@ -398,7 +399,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockInHand(HandSide handSide) throws WorldEditException {
|
||||
public BaseBlock getBlockInHand(HandSide handSide) throws WorldEditException {
|
||||
final ItemType typeId = getItemInHand(handSide).getType();
|
||||
if (typeId.hasBlockType()) {
|
||||
return typeId.getBlockType().getDefaultState().toBaseBlock();
|
||||
|
@ -319,7 +319,7 @@ public class PlatformManager {
|
||||
}
|
||||
|
||||
if (event.getType() == Interaction.HIT) {
|
||||
if (session.isToolControlEnabled() && playerActor.getItemInHand(HandSide.MAIN_HAND).getType().equals(getConfiguration().wandItem)) {
|
||||
if (session.isToolControlEnabled() && playerActor.getItemInHand(HandSide.MAIN_HAND).getType().getId().equals(getConfiguration().wandItem)) {
|
||||
FawePlayer<?> fp = FawePlayer.wrap(playerActor);
|
||||
if (!actor.hasPermission("worldedit.selection.pos")) {
|
||||
return;
|
||||
@ -378,7 +378,7 @@ public class PlatformManager {
|
||||
//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
|
||||
}
|
||||
} else if (event.getType() == Interaction.OPEN) {
|
||||
if (session.isToolControlEnabled() && playerActor.getItemInHand(HandSide.MAIN_HAND).getType().equals(getConfiguration().wandItem)) {
|
||||
if (session.isToolControlEnabled() && playerActor.getItemInHand(HandSide.MAIN_HAND).getType().getId().equals(getConfiguration().wandItem)) {
|
||||
FawePlayer<?> fp = FawePlayer.wrap(playerActor);
|
||||
if (!actor.hasPermission("worldedit.selection.pos")) {
|
||||
return;
|
||||
|
@ -20,7 +20,7 @@
|
||||
package com.sk89q.worldedit.extension.platform;
|
||||
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
@ -70,7 +70,7 @@ public class PlayerProxy extends AbstractPlayerActor {
|
||||
|
||||
|
||||
@Override
|
||||
public BlockState getBlockInHand(HandSide handSide) throws WorldEditException {
|
||||
public BaseBlock getBlockInHand(HandSide handSide) throws WorldEditException {
|
||||
return basePlayer.getBlockInHand(handSide);
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ public class AbstractDelegateExtent implements LightingExtent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getFullBlock(BlockVector3 position) {
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return extent.getFullBlock(position);
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ public class AbstractDelegateExtent implements LightingExtent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException {
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
|
||||
// mutable.mutX(x);
|
||||
// mutable.mutY(y);
|
||||
// mutable.mutZ(z);
|
||||
@ -150,7 +150,7 @@ public class AbstractDelegateExtent implements LightingExtent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(BlockVector3 location, BlockStateHolder block) throws WorldEditException {
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block) throws WorldEditException {
|
||||
return extent.setBlock(location, block);
|
||||
}
|
||||
|
||||
|
@ -118,19 +118,19 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
|
||||
@Override
|
||||
default BlockState getBlock(BlockVector3 position) {
|
||||
return getFullBlock(position);
|
||||
return getFullBlock(position).toImmutableState();
|
||||
}
|
||||
|
||||
@Override
|
||||
default BlockState getLazyBlock(BlockVector3 position) {
|
||||
return getFullBlock(position);
|
||||
return getFullBlock(position).toImmutableState();
|
||||
}
|
||||
|
||||
default BlockState getLazyBlock(int x, int y, int z) {
|
||||
return getLazyBlock(BlockVector3.at(x, y, z));
|
||||
}
|
||||
|
||||
default boolean setBlock(int x, int y, int z, BlockStateHolder state) throws WorldEditException {
|
||||
default <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T state) throws WorldEditException {
|
||||
return setBlock(BlockVector3.at(x, y, z), state);
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ public interface InputExtent {
|
||||
* @param position position of the block
|
||||
* @return the block
|
||||
*/
|
||||
BlockState getFullBlock(BlockVector3 position);
|
||||
BaseBlock getFullBlock(BlockVector3 position);
|
||||
|
||||
/**
|
||||
* Get the biome at the given location.
|
||||
|
@ -50,7 +50,7 @@ public interface OutputExtent {
|
||||
* @return true if the block was successfully set (return value may not be accurate)
|
||||
* @throws WorldEditException thrown on an error
|
||||
*/
|
||||
boolean setBlock(BlockVector3 position, BlockStateHolder block) throws WorldEditException;
|
||||
<T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block) throws WorldEditException;
|
||||
|
||||
/**
|
||||
* Set the biome.
|
||||
|
@ -234,8 +234,8 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent, Closeable
|
||||
//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
|
||||
|
||||
@Override
|
||||
public BlockState getFullBlock(BlockVector3 position) {
|
||||
return getLazyBlock(position);
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return getLazyBlock(position).toBaseBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,28 +19,220 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import com.boydti.fawe.object.clipboard.AbstractClipboardFormat;
|
||||
import com.boydti.fawe.object.io.PGZIPOutputStream;
|
||||
import com.boydti.fawe.object.io.ResettableFileInputStream;
|
||||
import com.boydti.fawe.object.schematic.PNGWriter;
|
||||
import com.boydti.fawe.object.schematic.StructureFormat;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.NBTConstants;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.jnbt.NamedTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
|
||||
/**
|
||||
* A collection of supported clipboard formats.
|
||||
*/
|
||||
@Deprecated
|
||||
public class BuiltInClipboardFormat {
|
||||
public static final ClipboardFormat MCEDIT_SCHEMATIC = ClipboardFormat.SCHEMATIC;
|
||||
public static final ClipboardFormat SPONGE_SCHEMATIC = ClipboardFormat.SPONGE_SCHEMATIC;
|
||||
public static final ClipboardFormat STRUCTURE = ClipboardFormat.STRUCTURE;
|
||||
public static final ClipboardFormat PNG = ClipboardFormat.PNG;
|
||||
|
||||
public enum BuiltInClipboardFormat implements ClipboardFormat{
|
||||
/**
|
||||
* The Schematic format used by many software.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final ClipboardFormat[] values() {
|
||||
return ClipboardFormat.values;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static ClipboardFormat valueOf(String value) {
|
||||
switch (value) {
|
||||
case "MCEDIT_SCHEMATIC":
|
||||
value = "SCHEMATIC";
|
||||
break;
|
||||
MCEDIT_SCHEMATIC("mcedit", "mce", "schematic") {
|
||||
@Override
|
||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||
if (inputStream instanceof FileInputStream) {
|
||||
inputStream = new ResettableFileInputStream((FileInputStream) inputStream);
|
||||
}
|
||||
BufferedInputStream buffered = new BufferedInputStream(inputStream);
|
||||
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered)));
|
||||
SchematicReader input = new SchematicReader(nbtStream);
|
||||
input.setUnderlyingStream(inputStream);
|
||||
return input;
|
||||
}
|
||||
return ClipboardFormat.valueOf(value);
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
throw new UnsupportedOperationException("No longer supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
try (NBTInputStream str = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)))) {
|
||||
NamedTag rootTag = str.readNamedTag();
|
||||
if (!rootTag.getName().equals("Schematic")) {
|
||||
return false;
|
||||
}
|
||||
CompoundTag schematicTag = (CompoundTag) rootTag.getTag();
|
||||
|
||||
// Check
|
||||
Map<String, Tag> schematic = schematicTag.getValue();
|
||||
if (!schematic.containsKey("Materials")) {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrimaryFileExtension() {
|
||||
return "schematic";
|
||||
}
|
||||
},
|
||||
|
||||
@Deprecated
|
||||
SPONGE_SCHEMATIC("sponge", "schem") {
|
||||
@Override
|
||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||
if (inputStream instanceof FileInputStream) {
|
||||
inputStream = new ResettableFileInputStream((FileInputStream) inputStream);
|
||||
}
|
||||
BufferedInputStream buffered = new BufferedInputStream(inputStream);
|
||||
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered)));
|
||||
SpongeSchematicReader input = new SpongeSchematicReader(nbtStream);
|
||||
return input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
OutputStream gzip;
|
||||
if (outputStream instanceof PGZIPOutputStream || outputStream instanceof GZIPOutputStream) {
|
||||
gzip = outputStream;
|
||||
} else {
|
||||
outputStream = new BufferedOutputStream(outputStream);
|
||||
PGZIPOutputStream pigz = new PGZIPOutputStream(outputStream);
|
||||
gzip = pigz;
|
||||
}
|
||||
NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip));
|
||||
return new SpongeSchematicWriter(nbtStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
try (NBTInputStream str = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)))) {
|
||||
NamedTag rootTag = str.readNamedTag();
|
||||
if (!rootTag.getName().equals("Schematic")) {
|
||||
return false;
|
||||
}
|
||||
CompoundTag schematicTag = (CompoundTag) rootTag.getTag();
|
||||
|
||||
// Check
|
||||
Map<String, Tag> schematic = schematicTag.getValue();
|
||||
if (!schematic.containsKey("Version")) {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrimaryFileExtension() {
|
||||
return "schem";
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The structure block format:
|
||||
* http://minecraft.gamepedia.com/Structure_block_file_format
|
||||
*/
|
||||
STRUCTURE("structure", "nbt") {
|
||||
@Override
|
||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||
inputStream = new BufferedInputStream(inputStream);
|
||||
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(inputStream)));
|
||||
return new StructureFormat(nbtStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
outputStream = new BufferedOutputStream(outputStream);
|
||||
OutputStream gzip;
|
||||
if (outputStream instanceof PGZIPOutputStream || outputStream instanceof GZIPOutputStream) {
|
||||
gzip = outputStream;
|
||||
} else {
|
||||
PGZIPOutputStream pigz = new PGZIPOutputStream(outputStream);
|
||||
gzip = pigz;
|
||||
}
|
||||
NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip));
|
||||
return new StructureFormat(nbtStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
return file.getName().endsWith(".nbt");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrimaryFileExtension() {
|
||||
return "nbt";
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Isometric PNG writer
|
||||
*/
|
||||
PNG("png", "image") {
|
||||
|
||||
@Override
|
||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
return new PNGWriter(new BufferedOutputStream(outputStream));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
return file.getName().endsWith(".png");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrimaryFileExtension() {
|
||||
return "png";
|
||||
}
|
||||
};
|
||||
|
||||
private final ImmutableSet<String> aliases;
|
||||
|
||||
BuiltInClipboardFormat(String... aliases) {
|
||||
this.aliases = ImmutableSet.copyOf(aliases);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAliases() {
|
||||
return this.aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getFileExtensions() {
|
||||
return ImmutableSet.of(getPrimaryFileExtension());
|
||||
}
|
||||
|
||||
}
|
@ -19,275 +19,84 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.jnbt.NBTStreamer;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.object.clipboard.*;
|
||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||
import com.boydti.fawe.object.clipboard.URIClipboardHolder;
|
||||
import com.boydti.fawe.object.io.PGZIPOutputStream;
|
||||
import com.boydti.fawe.object.io.ResettableFileInputStream;
|
||||
import com.boydti.fawe.object.schematic.PNGWriter;
|
||||
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.*;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
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.math.BlockVector3;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Array;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* A collection of supported clipboard formats.
|
||||
*/
|
||||
public enum ClipboardFormat {
|
||||
|
||||
/**
|
||||
* The Schematic format used by many software.
|
||||
*/
|
||||
@Deprecated
|
||||
SCHEMATIC(new AbstractClipboardFormat("SCHEMATIC", "mcedit", "mce", "schematic") {
|
||||
@Override
|
||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||
if (inputStream instanceof FileInputStream) {
|
||||
inputStream = new ResettableFileInputStream((FileInputStream) inputStream);
|
||||
}
|
||||
BufferedInputStream buffered = new BufferedInputStream(inputStream);
|
||||
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered)));
|
||||
SchematicReader input = new SchematicReader(nbtStream);
|
||||
input.setUnderlyingStream(inputStream);
|
||||
return input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
throw new UnsupportedOperationException("No longer supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
if (!file.getName().toLowerCase().endsWith(".schematic")) return false;
|
||||
DataInputStream str = null;
|
||||
try {
|
||||
str = new DataInputStream(new GZIPInputStream(new FileInputStream(file)));
|
||||
if ((str.readByte() & 0xFF) != NBTConstants.TYPE_COMPOUND) {
|
||||
return false;
|
||||
}
|
||||
byte[] nameBytes = new byte[str.readShort() & 0xFFFF];
|
||||
str.readFully(nameBytes);
|
||||
String name = new String(nameBytes, NBTConstants.CHARSET);
|
||||
return name.equals("Schematic");
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
} finally {
|
||||
if (str != null) {
|
||||
try {
|
||||
str.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtension() {
|
||||
return "schematic";
|
||||
}
|
||||
}),
|
||||
|
||||
@Deprecated
|
||||
SPONGE_SCHEMATIC(new AbstractClipboardFormat("SPONGE", "sponge", "schem") {
|
||||
@Override
|
||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||
if (inputStream instanceof FileInputStream) {
|
||||
inputStream = new ResettableFileInputStream((FileInputStream) inputStream);
|
||||
}
|
||||
BufferedInputStream buffered = new BufferedInputStream(inputStream);
|
||||
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered)));
|
||||
SpongeSchematicReader input = new SpongeSchematicReader(nbtStream);
|
||||
return input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
OutputStream gzip;
|
||||
if (outputStream instanceof PGZIPOutputStream || outputStream instanceof GZIPOutputStream) {
|
||||
gzip = outputStream;
|
||||
} else {
|
||||
outputStream = new BufferedOutputStream(outputStream);
|
||||
PGZIPOutputStream pigz = new PGZIPOutputStream(outputStream);
|
||||
gzip = pigz;
|
||||
}
|
||||
NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip));
|
||||
return new SpongeSchematicWriter(nbtStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
if (!file.getName().toLowerCase().endsWith(".schem")) return false;
|
||||
DataInputStream str = null;
|
||||
try {
|
||||
str = new DataInputStream(new GZIPInputStream(new FileInputStream(file)));
|
||||
if ((str.readByte() & 0xFF) != NBTConstants.TYPE_COMPOUND) {
|
||||
return false;
|
||||
}
|
||||
byte[] nameBytes = new byte[str.readShort() & 0xFFFF];
|
||||
str.readFully(nameBytes);
|
||||
String name = new String(nameBytes, NBTConstants.CHARSET);
|
||||
return name.equals("Schematic");
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
} finally {
|
||||
if (str != null) {
|
||||
try {
|
||||
str.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtension() {
|
||||
return "schem";
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* The structure block format:
|
||||
* http://minecraft.gamepedia.com/Structure_block_file_format
|
||||
*/
|
||||
STRUCTURE(new AbstractClipboardFormat("STRUCTURE", "structure", "nbt") {
|
||||
@Override
|
||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||
inputStream = new BufferedInputStream(inputStream);
|
||||
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(inputStream)));
|
||||
return new StructureFormat(nbtStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
outputStream = new BufferedOutputStream(outputStream);
|
||||
OutputStream gzip;
|
||||
if (outputStream instanceof PGZIPOutputStream || outputStream instanceof GZIPOutputStream) {
|
||||
gzip = outputStream;
|
||||
} else {
|
||||
PGZIPOutputStream pigz = new PGZIPOutputStream(outputStream);
|
||||
gzip = pigz;
|
||||
}
|
||||
NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip));
|
||||
return new StructureFormat(nbtStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
return file.getName().endsWith(".nbt");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtension() {
|
||||
return "nbt";
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Isometric PNG writer
|
||||
*/
|
||||
PNG(new AbstractClipboardFormat("PNG", "png", "image") {
|
||||
|
||||
@Override
|
||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
return new PNGWriter(new BufferedOutputStream(outputStream));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
return file.getName().endsWith(".png");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExtension() {
|
||||
return "png";
|
||||
}
|
||||
}),
|
||||
|
||||
;
|
||||
|
||||
public static final ClipboardFormat[] values;
|
||||
|
||||
private static final Map<String, ClipboardFormat> aliasMap;
|
||||
|
||||
static {
|
||||
aliasMap = new ConcurrentHashMap<>(8, 0.9f, 1);
|
||||
for (ClipboardFormat emum : ClipboardFormat.values()) {
|
||||
for (String alias : emum.getAliases()) {
|
||||
aliasMap.put(alias, emum);
|
||||
}
|
||||
}
|
||||
values = values();
|
||||
}
|
||||
|
||||
private IClipboardFormat format;
|
||||
|
||||
ClipboardFormat() {
|
||||
|
||||
}
|
||||
|
||||
ClipboardFormat(IClipboardFormat format) {
|
||||
this.format = format;
|
||||
}
|
||||
public interface ClipboardFormat {
|
||||
|
||||
/**
|
||||
* Returns the name of this format.
|
||||
*
|
||||
* @return The name of the format
|
||||
*/
|
||||
public String getName() {
|
||||
return name();
|
||||
}
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Get a set of aliases.
|
||||
*
|
||||
* @return a set of aliases
|
||||
*/
|
||||
Set<String> getAliases();
|
||||
|
||||
/**
|
||||
* Create a reader.
|
||||
*
|
||||
* @param inputStream the input stream
|
||||
* @return a reader
|
||||
* @throws IOException thrown on I/O error
|
||||
*/
|
||||
ClipboardReader getReader(InputStream inputStream) throws IOException;
|
||||
|
||||
/**
|
||||
* Create a writer.
|
||||
*
|
||||
* @param outputStream the output stream
|
||||
* @return a writer
|
||||
* @throws IOException thrown on I/O error
|
||||
*/
|
||||
ClipboardWriter getWriter(OutputStream outputStream) throws IOException;
|
||||
|
||||
/**
|
||||
* Return whether the given file is of this format.
|
||||
*
|
||||
* @param file the file
|
||||
* @return true if the given file is of this format
|
||||
*/
|
||||
boolean isFormat(File file);
|
||||
|
||||
/**
|
||||
* Get the file extension this format primarily uses.
|
||||
*
|
||||
* @return The primary file extension
|
||||
*/
|
||||
public String getPrimaryFileExtension() {
|
||||
return getExtension();
|
||||
}
|
||||
String getPrimaryFileExtension();
|
||||
|
||||
/**
|
||||
* Get the file extensions this format is commonly known to use. This should
|
||||
@ -295,12 +104,43 @@ public enum ClipboardFormat {
|
||||
*
|
||||
* @return The file extensions this format might be known by
|
||||
*/
|
||||
public Set<String> getFileExtensions() {
|
||||
return Collections.singleton(getPrimaryFileExtension());
|
||||
Set<String> getFileExtensions();
|
||||
|
||||
/**
|
||||
* Set the player's clipboard
|
||||
* @param player
|
||||
* @param uri
|
||||
* @param in
|
||||
* @return the held clipboard
|
||||
* @throws IOException
|
||||
*/
|
||||
default ClipboardHolder hold(Player player, URI uri, InputStream in) throws IOException {
|
||||
checkNotNull(player);
|
||||
checkNotNull(uri);
|
||||
checkNotNull(in);
|
||||
|
||||
final ClipboardReader reader = getReader(in);
|
||||
|
||||
final Clipboard clipboard;
|
||||
|
||||
LocalSession session = WorldEdit.getInstance().getSessionManager().get(player);
|
||||
session.setClipboard(null);
|
||||
clipboard = reader.read(player.getUniqueId());
|
||||
URIClipboardHolder holder = new URIClipboardHolder(uri, clipboard);
|
||||
session.setClipboard(holder);
|
||||
return holder;
|
||||
}
|
||||
|
||||
default Schematic load(File file) throws IOException {
|
||||
return load(new FileInputStream(file));
|
||||
}
|
||||
|
||||
|
||||
public URL uploadPublic(final Clipboard clipboard, String category, String user) {
|
||||
default Schematic load(InputStream stream) throws IOException {
|
||||
return new Schematic(getReader(stream).read());
|
||||
}
|
||||
|
||||
|
||||
default URL uploadPublic(final Clipboard clipboard, String category, String user) {
|
||||
// summary
|
||||
// blocks
|
||||
HashMap<String, Object> map = new HashMap<String, Object>();
|
||||
@ -318,158 +158,20 @@ public enum ClipboardFormat {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static MultiClipboardHolder loadAllFromInput(Actor player, String input, ClipboardFormat format, boolean message) throws IOException {
|
||||
checkNotNull(player);
|
||||
checkNotNull(input);
|
||||
WorldEdit worldEdit = WorldEdit.getInstance();
|
||||
LocalConfiguration config = worldEdit.getConfiguration();
|
||||
if (input.startsWith("url:")) {
|
||||
if (!player.hasPermission("worldedit.schematic.load.web")) {
|
||||
if (message) BBC.NO_PERM.send(player, "worldedit.schematic.load.web");
|
||||
return null;
|
||||
|
||||
default URL uploadAnonymous(final Clipboard clipboard) {
|
||||
return MainUtil.upload(null, null, getPrimaryFileExtension(), new RunnableVal<OutputStream>() {
|
||||
@Override
|
||||
public void run(OutputStream value) {
|
||||
write(value, clipboard);
|
||||
}
|
||||
URL base = new URL(Settings.IMP.WEB.URL);
|
||||
input = new URL(base, "uploads/" + input.substring(4) + ".schematic").toString();
|
||||
}
|
||||
if (input.startsWith("http")) {
|
||||
if (!player.hasPermission("worldedit.schematic.load.asset")) {
|
||||
if (message) BBC.NO_PERM.send(player, "worldedit.schematic.load.asset");
|
||||
return null;
|
||||
}
|
||||
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;
|
||||
}
|
||||
MultiClipboardHolder clipboards = loadAllFromUrl(url);
|
||||
return clipboards;
|
||||
} else {
|
||||
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}").matcher(input).find() && !player.hasPermission("worldedit.schematic.load.other")) {
|
||||
BBC.NO_PERM.send(player, "worldedit.schematic.load.other");
|
||||
return null;
|
||||
}
|
||||
File working = worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||
File dir = Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? new File(working, player.getUniqueId().toString()) : working;
|
||||
File f;
|
||||
if (input.startsWith("#")) {
|
||||
String[] extensions;
|
||||
if (format != null) {
|
||||
extensions = format.getFileExtensions().toArray(new String[0]);
|
||||
} else {
|
||||
extensions = ClipboardFormats.getFileExtensionArray();
|
||||
}
|
||||
f = player.openFileOpenDialog(extensions);
|
||||
if (f == null || !f.exists()) {
|
||||
if (message) player.printError("Schematic " + input + " does not exist! (" + f + ")");
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}").matcher(input).find() && !player.hasPermission("worldedit.schematic.load.other")) {
|
||||
if (message) BBC.NO_PERM.send(player, "worldedit.schematic.load.other");
|
||||
return null;
|
||||
}
|
||||
if (format == null && input.matches(".*\\.[\\w].*")) {
|
||||
String extension = input.substring(input.lastIndexOf('.') + 1, input.length());
|
||||
format = ClipboardFormat.findByExtension(extension);
|
||||
}
|
||||
f = MainUtil.resolve(dir, input, format, true);
|
||||
}
|
||||
if (f == null || !f.exists()) {
|
||||
if (!input.contains("../")) {
|
||||
dir = worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||
f = MainUtil.resolve(dir, input, format, true);
|
||||
}
|
||||
}
|
||||
if (f == null || !f.exists() || !MainUtil.isInSubDirectory(working, f)) {
|
||||
if (message) player.printError("Schematic " + input + " does not exist! (" + ((f == null) ? false : f.exists()) + "|" + f + "|" + (f == null ? false : !MainUtil.isInSubDirectory(working, f)) + ")");
|
||||
return null;
|
||||
}
|
||||
if (format == null && f.isFile()) {
|
||||
format = ClipboardFormat.findByFile(f);
|
||||
if (format == null) {
|
||||
BBC.CLIPBOARD_INVALID_FORMAT.send(player, f.getName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (!f.exists()) {
|
||||
if (message) BBC.SCHEMATIC_NOT_FOUND.send(player, input);
|
||||
return null;
|
||||
}
|
||||
if (!f.isDirectory()) {
|
||||
ByteSource source = Files.asByteSource(f);
|
||||
URI uri = f.toURI();
|
||||
return new MultiClipboardHolder(uri, new LazyClipboardHolder(f.toURI(), source, format, null));
|
||||
}
|
||||
URIClipboardHolder[] clipboards = loadAllFromDirectory(f);
|
||||
if (clipboards.length < 1) {
|
||||
if (message) BBC.SCHEMATIC_NOT_FOUND.send(player, input);
|
||||
return null;
|
||||
}
|
||||
return new MultiClipboardHolder(f.toURI(), clipboards);
|
||||
}
|
||||
}
|
||||
|
||||
public static URIClipboardHolder[] loadAllFromDirectory(File dir) {
|
||||
HashSet<String> extensions = new HashSet<>(Arrays.asList(ClipboardFormats.getFileExtensionArray()));
|
||||
File[] files = dir.listFiles(pathname -> {
|
||||
String input = pathname.getName();
|
||||
String extension = input.substring(input.lastIndexOf('.') + 1, input.length());
|
||||
return (extensions.contains(extension.toLowerCase()));
|
||||
});
|
||||
LazyClipboardHolder[] clipboards = new LazyClipboardHolder[files.length];
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File file = files[i];
|
||||
ByteSource source = Files.asByteSource(file);
|
||||
ClipboardFormat format = ClipboardFormat.findByFile(file);
|
||||
clipboards[i] = new LazyClipboardHolder(file.toURI(), source, format, null);
|
||||
}
|
||||
return clipboards;
|
||||
}
|
||||
|
||||
public static MultiClipboardHolder loadAllFromUrl(URL url) 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) {
|
||||
String filename = entry.getName();
|
||||
String extension = filename.substring(filename.lastIndexOf('.') + 1, filename.length());
|
||||
ClipboardFormat format = findByExtension(filename);
|
||||
if (format != null) {
|
||||
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(url.toURI(), source, format, null);
|
||||
clipboards.add(clipboard);
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
LazyClipboardHolder[] arr = clipboards.toArray(new LazyClipboardHolder[clipboards.size()]);
|
||||
try {
|
||||
MultiClipboardHolder multi = new MultiClipboardHolder(url.toURI());
|
||||
for (LazyClipboardHolder h : arr) multi.add(h);
|
||||
return multi;
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void write(OutputStream value, Clipboard clipboard) {
|
||||
|
||||
default void write(OutputStream value, Clipboard clipboard) {
|
||||
try {
|
||||
try (PGZIPOutputStream gzip = new PGZIPOutputStream(value)) {
|
||||
try (ClipboardWriter writer = format.getWriter(gzip)) {
|
||||
try (ClipboardWriter writer = getWriter(gzip)) {
|
||||
writer.write(clipboard);
|
||||
}
|
||||
}
|
||||
@ -477,164 +179,4 @@ public enum ClipboardFormat {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public URL uploadAnonymous(final Clipboard clipboard) {
|
||||
return MainUtil.upload(null, null, format.getExtension(), new RunnableVal<OutputStream>() {
|
||||
@Override
|
||||
public void run(OutputStream value) {
|
||||
write(value, clipboard);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public IClipboardFormat getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a set of aliases.
|
||||
*
|
||||
* @return a set of aliases
|
||||
*/
|
||||
public Set<String> getAliases() {
|
||||
return format.getAliases();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a reader.
|
||||
*
|
||||
* @param inputStream the input stream
|
||||
* @return a reader
|
||||
* @throws IOException thrown on I/O error
|
||||
*/
|
||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||
return format.getReader(inputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a writer.
|
||||
*
|
||||
* @param outputStream the output stream
|
||||
* @return a writer
|
||||
* @throws IOException thrown on I/O error
|
||||
*/
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
return format.getWriter(outputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the player's clipboard
|
||||
* @param player
|
||||
* @param uri
|
||||
* @param in
|
||||
* @return the held clipboard
|
||||
* @throws IOException
|
||||
*/
|
||||
public ClipboardHolder hold(Player player, URI uri, InputStream in) throws IOException {
|
||||
checkNotNull(player);
|
||||
checkNotNull(uri);
|
||||
checkNotNull(in);
|
||||
|
||||
final ClipboardReader reader = getReader(in);
|
||||
|
||||
final Clipboard clipboard;
|
||||
|
||||
LocalSession session = WorldEdit.getInstance().getSessionManager().get(player);
|
||||
session.setClipboard(null);
|
||||
clipboard = reader.read(player.getUniqueId());
|
||||
URIClipboardHolder holder = new URIClipboardHolder(uri, clipboard);
|
||||
session.setClipboard(holder);
|
||||
return holder;
|
||||
}
|
||||
|
||||
public Schematic load(File file) throws IOException {
|
||||
return load(new FileInputStream(file));
|
||||
}
|
||||
|
||||
public Schematic load(InputStream stream) throws IOException {
|
||||
return new Schematic(this.getReader(stream).read());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file extension used
|
||||
*
|
||||
* @return file extension string
|
||||
*/
|
||||
public String getExtension() {
|
||||
return format.getExtension();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given file is of this format.
|
||||
*
|
||||
* @param file the file
|
||||
* @return true if the given file is of this format
|
||||
*/
|
||||
public boolean isFormat(File file) {
|
||||
return format.isFormat(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the clipboard format named by the given alias.
|
||||
*
|
||||
* @param alias the alias
|
||||
* @return the format, otherwise null if none is matched
|
||||
*/
|
||||
@Nullable
|
||||
public static ClipboardFormat findByAlias(String alias) {
|
||||
checkNotNull(alias);
|
||||
return aliasMap.get(alias.toLowerCase(Locale.ENGLISH).trim());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ClipboardFormat findByExtension(String extension) {
|
||||
checkNotNull(extension);
|
||||
extension = extension.toLowerCase();
|
||||
for (ClipboardFormat format : values) {
|
||||
if (format.getFileExtensions().contains(extension)) {
|
||||
return format;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the format given a file.
|
||||
*
|
||||
* @param file the file
|
||||
* @return the format, otherwise null if one cannot be detected
|
||||
*/
|
||||
@Nullable
|
||||
public static ClipboardFormat findByFile(File file) {
|
||||
checkNotNull(file);
|
||||
for (ClipboardFormat format : EnumSet.allOf(ClipboardFormat.class)) {
|
||||
if (format.isFormat(file)) {
|
||||
return format;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ClipboardFormat addFormat(IClipboardFormat instance) {
|
||||
ClipboardFormat newEnum = ReflectionUtils.addEnum(ClipboardFormat.class, instance.getName());
|
||||
newEnum.format = instance;
|
||||
for (String alias : newEnum.getAliases()) {
|
||||
aliasMap.put(alias, newEnum);
|
||||
}
|
||||
|
||||
ArrayList<ClipboardFormat> newValues = new ArrayList<>(Arrays.asList(values));
|
||||
newValues.add(newEnum);
|
||||
ClipboardFormat[] newValuesArray = newValues.toArray(new ClipboardFormat[newValues.size()]);
|
||||
try {
|
||||
ReflectionUtils.setFailsafeFieldValue(ClipboardFormat.class.getDeclaredField("values"), null, newValuesArray);
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return newEnum;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -19,17 +19,77 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
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.util.MainUtil;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.google.common.io.ByteSource;
|
||||
import com.google.common.io.Files;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import java.io.File;
|
||||
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;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class ClipboardFormats {
|
||||
|
||||
private static final Map<String, ClipboardFormat> aliasMap = new HashMap<>();
|
||||
private static final Multimap<String, ClipboardFormat> fileExtensionMap = HashMultimap.create();
|
||||
private static final List<ClipboardFormat> registeredFormats = new ArrayList<>();
|
||||
|
||||
public static void registerClipboardFormat(ClipboardFormat format) {
|
||||
checkNotNull(format);
|
||||
|
||||
for (String key : format.getAliases()) {
|
||||
String lowKey = key.toLowerCase(Locale.ENGLISH);
|
||||
ClipboardFormat old = aliasMap.put(lowKey, format);
|
||||
if (old != null) {
|
||||
aliasMap.put(lowKey, old);
|
||||
WorldEdit.logger.warning(format.getClass().getName() + " cannot override existing alias '" + lowKey + "' used by " + old.getClass().getName());
|
||||
}
|
||||
}
|
||||
for (String ext : format.getFileExtensions()) {
|
||||
String lowExt = ext.toLowerCase(Locale.ENGLISH);
|
||||
fileExtensionMap.put(lowExt, format);
|
||||
}
|
||||
registeredFormats.add(format);
|
||||
}
|
||||
|
||||
static {
|
||||
for (BuiltInClipboardFormat format : BuiltInClipboardFormat.values()) {
|
||||
registerClipboardFormat(format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the clipboard format named by the given alias.
|
||||
*
|
||||
@ -39,7 +99,8 @@ public class ClipboardFormats {
|
||||
*/
|
||||
@Nullable
|
||||
public static ClipboardFormat findByAlias(String alias) {
|
||||
return ClipboardFormat.findByAlias(alias);
|
||||
checkNotNull(alias);
|
||||
return aliasMap.get(alias.toLowerCase(Locale.ENGLISH).trim());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,7 +114,7 @@ public class ClipboardFormats {
|
||||
public static ClipboardFormat findByFile(File file) {
|
||||
checkNotNull(file);
|
||||
|
||||
for (ClipboardFormat format : ClipboardFormat.values) {
|
||||
for (ClipboardFormat format : registeredFormats) {
|
||||
if (format.isFormat(file)) {
|
||||
return format;
|
||||
}
|
||||
@ -61,22 +122,36 @@ public class ClipboardFormats {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the format using the given extension
|
||||
* @param string
|
||||
* the extension
|
||||
* @return the format, otherwise null if one cannot be detected
|
||||
*/
|
||||
@Nullable
|
||||
public static ClipboardFormat findByExtension(String extension) {
|
||||
checkNotNull(extension);
|
||||
|
||||
Collection<Entry<String, ClipboardFormat>> entries = getFileExtensionMap().entries();
|
||||
for(Map.Entry<String, ClipboardFormat> entry : entries) {
|
||||
if(entry.getKey().equalsIgnoreCase(extension)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a multimap from a file extension to the potential matching formats.
|
||||
*/
|
||||
public static Multimap<String, ClipboardFormat> getFileExtensionMap() {
|
||||
HashMultimap<String, ClipboardFormat> map = HashMultimap.create();
|
||||
for (ClipboardFormat format : ClipboardFormat.values) {
|
||||
for (String ext : format.getFileExtensions()) {
|
||||
map.put(ext, format);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
return Multimaps.unmodifiableMultimap(fileExtensionMap);
|
||||
}
|
||||
|
||||
public static Collection<ClipboardFormat> getAll() {
|
||||
return Arrays.asList(ClipboardFormat.values);
|
||||
return Collections.unmodifiableCollection(registeredFormats);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,13 +159,156 @@ public class ClipboardFormats {
|
||||
* It is not in SchematicCommands because it may rely on internal register calls.
|
||||
*/
|
||||
public static String[] getFileExtensionArray() {
|
||||
List<String> exts = new ArrayList<>();
|
||||
HashMultimap<String, ClipboardFormat> map = HashMultimap.create();
|
||||
for (ClipboardFormat format : ClipboardFormat.values) {
|
||||
exts.addAll(format.getFileExtensions());
|
||||
}
|
||||
return exts.toArray(new String[exts.size()]);
|
||||
return fileExtensionMap.keySet().toArray(new String[fileExtensionMap.keySet().size()]);
|
||||
}
|
||||
|
||||
private ClipboardFormats() {}
|
||||
private ClipboardFormats() {
|
||||
}
|
||||
|
||||
public static MultiClipboardHolder loadAllFromInput(Actor player, String input, ClipboardFormat format, boolean message) throws IOException {
|
||||
checkNotNull(player);
|
||||
checkNotNull(input);
|
||||
WorldEdit worldEdit = WorldEdit.getInstance();
|
||||
LocalConfiguration config = worldEdit.getConfiguration();
|
||||
if (input.startsWith("url:")) {
|
||||
if (!player.hasPermission("worldedit.schematic.load.web")) {
|
||||
if (message) BBC.NO_PERM.send(player, "worldedit.schematic.load.web");
|
||||
return null;
|
||||
}
|
||||
URL base = new URL(Settings.IMP.WEB.URL);
|
||||
input = new URL(base, "uploads/" + input.substring(4) + ".schematic").toString();
|
||||
}
|
||||
if (input.startsWith("http")) {
|
||||
if (!player.hasPermission("worldedit.schematic.load.asset")) {
|
||||
if (message) BBC.NO_PERM.send(player, "worldedit.schematic.load.asset");
|
||||
return null;
|
||||
}
|
||||
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;
|
||||
}
|
||||
MultiClipboardHolder clipboards = loadAllFromUrl(url);
|
||||
return clipboards;
|
||||
} else {
|
||||
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}").matcher(input).find() && !player.hasPermission("worldedit.schematic.load.other")) {
|
||||
BBC.NO_PERM.send(player, "worldedit.schematic.load.other");
|
||||
return null;
|
||||
}
|
||||
File working = worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||
File dir = Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS ? new File(working, player.getUniqueId().toString()) : working;
|
||||
File f;
|
||||
if (input.startsWith("#")) {
|
||||
String[] extensions;
|
||||
if (format != null) {
|
||||
extensions = format.getFileExtensions().toArray(new String[0]);
|
||||
} else {
|
||||
extensions = ClipboardFormats.getFileExtensionArray();
|
||||
}
|
||||
f = player.openFileOpenDialog(extensions);
|
||||
if (f == null || !f.exists()) {
|
||||
if (message) player.printError("Schematic " + input + " does not exist! (" + f + ")");
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if (Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS && Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}").matcher(input).find() && !player.hasPermission("worldedit.schematic.load.other")) {
|
||||
if (message) BBC.NO_PERM.send(player, "worldedit.schematic.load.other");
|
||||
return null;
|
||||
}
|
||||
if (format == null && input.matches(".*\\.[\\w].*")) {
|
||||
String extension = input.substring(input.lastIndexOf('.') + 1, input.length());
|
||||
format = findByExtension(extension);
|
||||
}
|
||||
f = MainUtil.resolve(dir, input, format, true);
|
||||
}
|
||||
if (f == null || !f.exists()) {
|
||||
if (!input.contains("../")) {
|
||||
dir = worldEdit.getWorkingDirectoryFile(config.saveDir);
|
||||
f = MainUtil.resolve(dir, input, format, true);
|
||||
}
|
||||
}
|
||||
if (f == null || !f.exists() || !MainUtil.isInSubDirectory(working, f)) {
|
||||
if (message) player.printError("Schematic " + input + " does not exist! (" + ((f == null) ? false : f.exists()) + "|" + f + "|" + (f == null ? false : !MainUtil.isInSubDirectory(working, f)) + ")");
|
||||
return null;
|
||||
}
|
||||
if (format == null && f.isFile()) {
|
||||
format = findByFile(f);
|
||||
if (format == null) {
|
||||
BBC.CLIPBOARD_INVALID_FORMAT.send(player, f.getName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (!f.exists()) {
|
||||
if (message) BBC.SCHEMATIC_NOT_FOUND.send(player, input);
|
||||
return null;
|
||||
}
|
||||
if (!f.isDirectory()) {
|
||||
ByteSource source = Files.asByteSource(f);
|
||||
URI uri = f.toURI();
|
||||
return new MultiClipboardHolder(uri, new LazyClipboardHolder(f.toURI(), source, format, null));
|
||||
}
|
||||
URIClipboardHolder[] clipboards = loadAllFromDirectory(f);
|
||||
if (clipboards.length < 1) {
|
||||
if (message) BBC.SCHEMATIC_NOT_FOUND.send(player, input);
|
||||
return null;
|
||||
}
|
||||
return new MultiClipboardHolder(f.toURI(), clipboards);
|
||||
}
|
||||
}
|
||||
|
||||
public static URIClipboardHolder[] loadAllFromDirectory(File dir) {
|
||||
HashSet<String> extensions = new HashSet<>(Arrays.asList(ClipboardFormats.getFileExtensionArray()));
|
||||
File[] files = dir.listFiles(pathname -> {
|
||||
String input = pathname.getName();
|
||||
String extension = input.substring(input.lastIndexOf('.') + 1, input.length());
|
||||
return (extensions.contains(extension.toLowerCase()));
|
||||
});
|
||||
LazyClipboardHolder[] clipboards = new LazyClipboardHolder[files.length];
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File file = files[i];
|
||||
ByteSource source = Files.asByteSource(file);
|
||||
ClipboardFormat format = findByFile(file);
|
||||
clipboards[i] = new LazyClipboardHolder(file.toURI(), source, format, null);
|
||||
}
|
||||
return clipboards;
|
||||
}
|
||||
|
||||
public static MultiClipboardHolder loadAllFromUrl(URL url) 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) {
|
||||
String filename = entry.getName();
|
||||
String extension = filename.substring(filename.lastIndexOf('.') + 1, filename.length());
|
||||
ClipboardFormat format = findByExtension(filename);
|
||||
if (format != null) {
|
||||
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(url.toURI(), source, format, null);
|
||||
clipboards.add(clipboard);
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
LazyClipboardHolder[] arr = clipboards.toArray(new LazyClipboardHolder[clipboards.size()]);
|
||||
try {
|
||||
MultiClipboardHolder multi = new MultiClipboardHolder(url.toURI());
|
||||
for (LazyClipboardHolder h : arr) multi.add(h);
|
||||
return multi;
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,335 +1,330 @@
|
||||
/*
|
||||
* 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.extent.transform;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.jnbt.ByteTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.internal.helper.MCDirections;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.registry.state.AbstractProperty;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
import com.sk89q.worldedit.math.transform.Transform;
|
||||
import com.sk89q.worldedit.registry.state.BooleanProperty;
|
||||
import com.sk89q.worldedit.registry.state.DirectionalProperty;
|
||||
import com.sk89q.worldedit.registry.state.EnumProperty;
|
||||
import com.sk89q.worldedit.registry.state.IntegerProperty;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Transforms blocks themselves (but not their position) according to a
|
||||
* given transform.
|
||||
*/
|
||||
public class BlockTransformExtent extends ResettableExtent {
|
||||
private Transform transform;
|
||||
private Transform transformInverse;
|
||||
private int[] BLOCK_ROTATION_BITMASK;
|
||||
private int[][] BLOCK_TRANSFORM;
|
||||
private int[][] BLOCK_TRANSFORM_INVERSE;
|
||||
private int[] ALL = new int[0];
|
||||
|
||||
private Transform transform;
|
||||
|
||||
|
||||
public BlockTransformExtent(Extent parent) {
|
||||
this(parent, new AffineTransform());
|
||||
}
|
||||
|
||||
public BlockTransformExtent(Extent parent, Transform transform) {
|
||||
super(parent);
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param extent the extent
|
||||
*/
|
||||
public BlockTransformExtent(Extent extent, Transform transform) {
|
||||
super(extent);
|
||||
checkNotNull(transform);
|
||||
this.transform = transform;
|
||||
this.transformInverse = this.transform.inverse();
|
||||
cache();
|
||||
}
|
||||
|
||||
private List<Direction> getDirections(AbstractProperty property) {
|
||||
if (property instanceof DirectionalProperty) {
|
||||
DirectionalProperty directional = (DirectionalProperty) property;
|
||||
directional.getValues();
|
||||
} else {
|
||||
switch (property.getKey()) {
|
||||
case HALF:
|
||||
|
||||
case ROTATION:
|
||||
|
||||
case AXIS:
|
||||
|
||||
case FACING:
|
||||
|
||||
case SHAPE:
|
||||
|
||||
case NORTH:
|
||||
case EAST:
|
||||
case SOUTH:
|
||||
case WEST:
|
||||
}
|
||||
}
|
||||
return null;
|
||||
/**
|
||||
* Get the transform.
|
||||
*
|
||||
* @return the transform
|
||||
*/
|
||||
public Transform getTransform() {
|
||||
return transform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the transform
|
||||
* @param affine
|
||||
*/
|
||||
public void setTransform(Transform affine) {
|
||||
this.transform = affine;
|
||||
}
|
||||
// @Override
|
||||
// public BlockState getBlock(BlockVector3 position) {
|
||||
// return transformBlock(super.getBlock(position), false);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
// return transformBlock(super.getFullBlock(position), false);
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public boolean setBlock(BlockVector3 location, BlockStateHolder block) throws WorldEditException {
|
||||
// return super.setBlock(location, transformBlock(block, true));
|
||||
// }
|
||||
|
||||
|
||||
// /**
|
||||
// * Transform the given block using the given transform.
|
||||
// *
|
||||
// * <p>The provided block is modified.</p>
|
||||
// *
|
||||
// * @param block the block
|
||||
// * @param transform the transform
|
||||
// * @return the same block
|
||||
// */
|
||||
// public static <T extends BlockStateHolder> T transform(T block, Transform transform) {
|
||||
// return transform(block, transform, block);
|
||||
// }
|
||||
/**
|
||||
* Transform a block without making a copy.
|
||||
*
|
||||
* @param block the block
|
||||
* @param reverse true to transform in the opposite direction
|
||||
* @return the same block
|
||||
*/
|
||||
private <T extends BlockStateHolder<T>> T transformBlock(T block, boolean reverse) {
|
||||
return transform(block, reverse ? transform.inverse() : transform);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(BlockVector3 position) {
|
||||
return transformFast(super.getLazyBlock(position)).toImmutableState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(int x, int y, int z) {
|
||||
return transformFast(super.getLazyBlock(x, y, z)).toImmutableState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
return transformFast(super.getBlock(position)).toImmutableState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return transformFast(super.getFullBlock(position).toImmutableState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) throws WorldEditException {
|
||||
return super.setBlock(x, y, z, transformFastInverse((BlockState)block));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
|
||||
return super.setBlock(location, transformFastInverse((BlockState)block));
|
||||
}
|
||||
|
||||
private static final Set<String> directionNames = Sets.newHashSet("north", "south", "east", "west");
|
||||
|
||||
// /**
|
||||
// * Transform the given block using the given transform.
|
||||
// *
|
||||
// * @param block the block
|
||||
// * @param transform the transform
|
||||
// * @param changedBlock the block to change
|
||||
// * @return the changed block
|
||||
// */
|
||||
// private static <T extends BlockStateHolder> T transform(T block, Transform transform, T changedBlock) {
|
||||
// checkNotNull(block);
|
||||
// checkNotNull(transform);
|
||||
//
|
||||
// List<? extends Property> properties = block.getBlockType().getProperties();
|
||||
//
|
||||
// for (Property property : properties) {
|
||||
// if (property instanceof DirectionalProperty) {
|
||||
// Direction value = (Direction) block.getState(property);
|
||||
// if (value != null) {
|
||||
// Vector3 newValue = getNewStateValue((DirectionalProperty) property, transform, value.toVector());
|
||||
// if (newValue != null) {
|
||||
// changedBlock = (T) changedBlock.with(property, Direction.findClosest(newValue, Direction.Flag.ALL));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
/**
|
||||
* Transform the given block using the given transform.
|
||||
*
|
||||
* <p>The provided block is <em>not</em> modified.</p>
|
||||
*
|
||||
* @param block the block
|
||||
* @param transform the transform
|
||||
* @return the same block
|
||||
*/
|
||||
public static <B extends BlockStateHolder<B>> B transform(B block, Transform transform) {
|
||||
checkNotNull(block);
|
||||
checkNotNull(transform);
|
||||
B result = block;
|
||||
List<? extends Property<?>> properties = block.getBlockType().getProperties();
|
||||
|
||||
for (Property<?> property : properties) {
|
||||
if (property instanceof DirectionalProperty) {
|
||||
DirectionalProperty dirProp = (DirectionalProperty) property;
|
||||
Direction value = (Direction) block.getState(property);
|
||||
if (value != null) {
|
||||
Vector3 newValue = getNewStateValue(dirProp.getValues(), transform, value.toVector());
|
||||
if (newValue != null) {
|
||||
result = result.with(dirProp, Direction.findClosest(newValue, Direction.Flag.ALL));
|
||||
}
|
||||
}
|
||||
} else if (property instanceof EnumProperty) {
|
||||
EnumProperty enumProp = (EnumProperty) property;
|
||||
if (property.getName().equals("axis")) {
|
||||
// We have an axis - this is something we can do the rotations to :sunglasses:
|
||||
Direction value = null;
|
||||
switch ((String) block.getState(property)) {
|
||||
case "x":
|
||||
value = Direction.EAST;
|
||||
break;
|
||||
case "y":
|
||||
value = Direction.UP;
|
||||
break;
|
||||
case "z":
|
||||
value = Direction.NORTH;
|
||||
break;
|
||||
}
|
||||
if (value != null) {
|
||||
Vector3 newValue = getNewStateValue(Direction.valuesOf(Direction.Flag.UPRIGHT | Direction.Flag.CARDINAL), transform, value.toVector());
|
||||
if (newValue != null) {
|
||||
String axis = null;
|
||||
Direction newDir = Direction.findClosest(newValue, Direction.Flag.UPRIGHT | Direction.Flag.CARDINAL);
|
||||
if (newDir == Direction.NORTH || newDir == Direction.SOUTH) {
|
||||
axis = "z";
|
||||
} else if (newDir == Direction.EAST || newDir == Direction.WEST) {
|
||||
axis = "x";
|
||||
} else if (newDir == Direction.UP || newDir == Direction.DOWN) {
|
||||
axis = "y";
|
||||
}
|
||||
if (axis != null) {
|
||||
result = result.with(enumProp, axis);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (property instanceof IntegerProperty) {
|
||||
IntegerProperty intProp = (IntegerProperty) property;
|
||||
if (property.getName().equals("rotation")) {
|
||||
if (intProp.getValues().size() == 16) {
|
||||
Optional<Direction> direction = Direction.fromRotationIndex(block.getState(intProp));
|
||||
int horizontalFlags = Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL;
|
||||
if (direction.isPresent()) {
|
||||
Vector3 vec = getNewStateValue(Direction.valuesOf(horizontalFlags), transform, direction.get().toVector());
|
||||
if (vec != null) {
|
||||
OptionalInt newRotation = Direction.findClosest(vec, horizontalFlags).toRotationIndex();
|
||||
if (newRotation.isPresent()) {
|
||||
result = result.with(intProp, newRotation.getAsInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<String> directionalProperties = properties.stream()
|
||||
.filter(prop -> prop instanceof BooleanProperty)
|
||||
.filter(prop -> directionNames.contains(prop.getName()))
|
||||
.filter(property -> (Boolean) block.getState(property))
|
||||
.map(Property::getName)
|
||||
.map(String::toUpperCase)
|
||||
.map(Direction::valueOf)
|
||||
.map(dir -> Direction.findClosest(transform.apply(dir.toVector()), Direction.Flag.CARDINAL))
|
||||
.filter(Objects::nonNull)
|
||||
.map(Direction::name)
|
||||
.map(String::toLowerCase)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (directionalProperties.size() > 0) {
|
||||
for (String directionName : directionNames) {
|
||||
result = result.with(block.getBlockType().getProperty(directionName), directionalProperties.contains(directionName));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public final BaseBlock transformFast(BlockState block) {
|
||||
BaseBlock transformed = transformBlock(block, false).toBaseBlock();
|
||||
if (block.hasNbtData()) {
|
||||
CompoundTag tag = block.getNbtData();
|
||||
if (tag.containsKey("Rot")) {
|
||||
int rot = tag.asInt("Rot");
|
||||
|
||||
Direction direction = Direction.fromRotationIndex(rot).get();
|
||||
|
||||
if (direction != null) {
|
||||
Vector3 applyAbsolute = transform.apply(direction.toVector());
|
||||
Vector3 applyOrigin = transform.apply(Vector3.ZERO);
|
||||
Vector3 newAbsolute = Vector3.at(applyAbsolute.getX() - applyOrigin.getX(), applyAbsolute.getY() - applyOrigin.getY(), applyAbsolute.getZ() - applyOrigin.getZ());
|
||||
|
||||
Direction newDirection = Direction.findClosest(newAbsolute, Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL);
|
||||
|
||||
if (newDirection != null) {
|
||||
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
|
||||
values.put("Rot", new ByteTag((byte) newDirection.toRotationIndex().getAsInt()));
|
||||
}
|
||||
}
|
||||
transformed.setNbtData(tag);
|
||||
}
|
||||
}
|
||||
return transformed;
|
||||
}
|
||||
|
||||
public final BaseBlock transformFastInverse(BlockState block) {
|
||||
BaseBlock transformed = transformBlock(block, true).toBaseBlock();
|
||||
if (block.hasNbtData()) {
|
||||
CompoundTag tag = block.getNbtData();
|
||||
if (tag.containsKey("Rot")) {
|
||||
int rot = tag.asInt("Rot");
|
||||
|
||||
Direction direction = Direction.fromRotationIndex(rot).get();
|
||||
|
||||
if (direction != null) {
|
||||
Vector3 applyAbsolute = getTransform().inverse().apply(direction.toVector());
|
||||
Vector3 applyOrigin = getTransform().inverse().apply(Vector3.ZERO);
|
||||
|
||||
Vector3 newAbsolute = Vector3.at(applyAbsolute.getX() - applyOrigin.getX(), applyAbsolute.getY() - applyOrigin.getY(), applyAbsolute.getZ() - applyOrigin.getZ());
|
||||
|
||||
Direction newDirection = Direction.findClosest(newAbsolute, Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL);
|
||||
|
||||
if (newDirection != null) {
|
||||
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
|
||||
values.put("Rot", new ByteTag((byte) newDirection.toRotationIndex().getAsInt()));
|
||||
}
|
||||
}
|
||||
}
|
||||
transformed.setNbtData(tag);
|
||||
}
|
||||
return transformed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the new value with the transformed direction.
|
||||
*
|
||||
* @param allowedStates the allowed states
|
||||
* @param transform the transform
|
||||
* @param oldDirection the old direction to transform
|
||||
* @return a new state or null if none could be found
|
||||
*/
|
||||
@Nullable
|
||||
//<<<<<<< HEAD
|
||||
private static Integer getNewStateIndex(Transform transform, List<Direction> directions, int oldIndex) {
|
||||
Direction oldDirection = directions.get(oldIndex);
|
||||
Vector3 oldVector = oldDirection.toVector();
|
||||
Vector3 newVector = transform.apply(oldVector).subtract(transform.apply(Vector3.ZERO)).normalize();
|
||||
int newIndex = oldIndex;
|
||||
double closest = oldVector.normalize().dot(newVector);
|
||||
//=======
|
||||
// private static Vector3 getNewStateValue(DirectionalProperty state, Transform transform, Vector3 oldDirection) {
|
||||
// Vector3 newDirection = transform.apply(oldDirection).subtract(transform.apply(Vector3.ZERO)).normalize();
|
||||
// Vector3 newValue = null;
|
||||
// double closest = -2;
|
||||
//>>>>>>> 399e0ad5... Refactor vector system to be cleaner
|
||||
private static Vector3 getNewStateValue(List<Direction> allowedStates, Transform transform, Vector3 oldDirection) {
|
||||
Vector3 newDirection = transform.apply(oldDirection).subtract(transform.apply(Vector3.ZERO)).normalize();
|
||||
Vector3 newValue = null;
|
||||
double closest = -2;
|
||||
boolean found = false;
|
||||
|
||||
for (int i = 0; i < directions.size(); i++) {
|
||||
Direction v = directions.get(i);
|
||||
double dot = v.toVector().normalize().dot(newVector);
|
||||
if (dot > closest) {
|
||||
for (Direction v : allowedStates) {
|
||||
double dot = v.toVector().normalize().dot(newDirection);
|
||||
if (dot >= closest) {
|
||||
closest = dot;
|
||||
newIndex = i;
|
||||
newValue = v.toVector();
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
return newIndex;
|
||||
return newValue;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void cache() {
|
||||
BLOCK_ROTATION_BITMASK = new int[BlockTypes.size()];
|
||||
BLOCK_TRANSFORM = new int[BlockTypes.size()][];
|
||||
BLOCK_TRANSFORM_INVERSE = new int[BlockTypes.size()][];
|
||||
outer:
|
||||
for (int i = 0; i < BLOCK_TRANSFORM.length; i++) {
|
||||
BLOCK_TRANSFORM[i] = ALL;
|
||||
BLOCK_TRANSFORM_INVERSE[i] = ALL;
|
||||
BlockTypes type = BlockTypes.get(i);
|
||||
int bitMask = 0;
|
||||
for (AbstractProperty property : (Collection<AbstractProperty>) type.getProperties()) {
|
||||
Collection<Direction> directions = getDirections(property);
|
||||
if (directions != null) {
|
||||
BLOCK_TRANSFORM[i] = null;
|
||||
BLOCK_TRANSFORM_INVERSE[i] = null;
|
||||
bitMask |= property.getBitMask();
|
||||
}
|
||||
}
|
||||
if (bitMask != 0) {
|
||||
BLOCK_ROTATION_BITMASK[i] = bitMask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResettableExtent setExtent(Extent extent) {
|
||||
return super.setExtent(extent);
|
||||
}
|
||||
|
||||
public Transform getTransform() {
|
||||
return transform;
|
||||
}
|
||||
|
||||
public void setTransform(Transform affine) {
|
||||
this.transform = affine;
|
||||
this.transformInverse = this.transform.inverse();
|
||||
cache();
|
||||
}
|
||||
|
||||
private final BlockState transform(BlockState state, int[][] transformArray, Transform transform) {
|
||||
int typeId = state.getInternalBlockTypeId();
|
||||
int[] arr = transformArray[typeId];
|
||||
if (arr == ALL) return state;
|
||||
if (arr == null) {
|
||||
arr = transformArray[typeId] = new int[state.getBlockType().getMaxStateId() + 1];
|
||||
Arrays.fill(arr, -1);
|
||||
}
|
||||
int mask = BLOCK_ROTATION_BITMASK[typeId];
|
||||
int internalId = state.getInternalId();
|
||||
|
||||
int maskedId = internalId & mask;
|
||||
int newMaskedId = arr[maskedId];
|
||||
if (newMaskedId != -1) {
|
||||
return BlockState.getFromInternalId(newMaskedId | (internalId & (~mask)));
|
||||
}
|
||||
newMaskedId = state.getInternalId();
|
||||
|
||||
BlockTypes type = state.getBlockType();
|
||||
for (AbstractProperty property : (Collection<AbstractProperty>) type.getProperties()) {
|
||||
List<Direction> directions = getDirections(property);
|
||||
if (directions != null) {
|
||||
Integer newIndex = getNewStateIndex(transform, directions, property.getIndex(state.getInternalId()));
|
||||
if (newIndex != null) {
|
||||
newMaskedId = property.modifyIndex(newMaskedId, newIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
arr[maskedId] = newMaskedId & mask;
|
||||
return BlockState.getFromInternalId(newMaskedId);
|
||||
}
|
||||
|
||||
public final BlockState transformFast(BlockState block) {
|
||||
BlockState transformed = transform(block, BLOCK_TRANSFORM, transform);
|
||||
if (block.hasNbtData()) {
|
||||
CompoundTag tag = block.getNbtData();
|
||||
if (tag.containsKey("Rot")) {
|
||||
int rot = tag.asInt("Rot");
|
||||
|
||||
Direction direction = MCDirections.fromRotation(rot);
|
||||
|
||||
if (direction != null) {
|
||||
Vector3 applyAbsolute = transform.apply(direction.toVector());
|
||||
Vector3 applyOrigin = transform.apply(Vector3.ZERO);
|
||||
|
||||
Direction newDirection = Direction.findClosest(applyAbsolute.subtract(applyOrigin), Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL);
|
||||
|
||||
if (newDirection != null) {
|
||||
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
|
||||
values.put("Rot", new ByteTag((byte) MCDirections.toRotation(newDirection)));
|
||||
}
|
||||
}
|
||||
transformed = new BaseBlock(transformed, tag);
|
||||
}
|
||||
}
|
||||
return transformed;
|
||||
}
|
||||
|
||||
public final BlockState transformFastInverse(BlockState block) {
|
||||
BlockState transformed = transform(block, BLOCK_TRANSFORM_INVERSE, transformInverse);
|
||||
if (block.hasNbtData()) {
|
||||
CompoundTag tag = block.getNbtData();
|
||||
if (tag.containsKey("Rot")) {
|
||||
int rot = tag.asInt("Rot");
|
||||
|
||||
Direction direction = MCDirections.fromRotation(rot);
|
||||
|
||||
if (direction != null) {
|
||||
Vector3 applyAbsolute = transformInverse.apply(direction.toVector());
|
||||
Vector3 applyOrigin = transformInverse.apply(Vector3.ZERO);
|
||||
|
||||
Direction newDirection = Direction.findClosest(applyAbsolute.subtract(applyOrigin), Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL);
|
||||
|
||||
if (newDirection != null) {
|
||||
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
|
||||
values.put("Rot", new ByteTag((byte) MCDirections.toRotation(newDirection)));
|
||||
}
|
||||
}
|
||||
}
|
||||
transformed = new BaseBlock(transformed, tag);
|
||||
}
|
||||
return transformed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(int x, int y, int z) {
|
||||
return transformFast(super.getLazyBlock(x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(BlockVector3 position) {
|
||||
return transformFast(super.getLazyBlock(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
return transformFast(super.getBlock(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBiome getBiome(BlockVector2 position) {
|
||||
return super.getBiome(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException {
|
||||
return super.setBlock(x, y, z, transformFastInverse((BlockState) block));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean setBlock(BlockVector3 location, BlockStateHolder block) throws WorldEditException {
|
||||
return super.setBlock(location, transformFastInverse((BlockState) block));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -62,7 +62,7 @@ public class BlockMask extends AbstractExtentMask {
|
||||
for (int i = 0; i < bitSets.length; i++) {
|
||||
if (bitSets[i] != null) {
|
||||
long[] set = bitSets[i];
|
||||
BlockTypes type = BlockTypes.get(i);
|
||||
BlockType type = BlockTypes.get(i);
|
||||
if (set == ALL) {
|
||||
strings.add(type.getId());
|
||||
} else {
|
||||
@ -137,7 +137,7 @@ public class BlockMask extends AbstractExtentMask {
|
||||
boolean single = true;
|
||||
int and = type.getInternalId();
|
||||
List<? extends Property> properties = type.getProperties();
|
||||
for (AbstractProperty prop : (List<AbstractProperty>) type.getProperties()) {
|
||||
for (AbstractProperty prop : (List<AbstractProperty<?>>) type.getProperties()) {
|
||||
List values = prop.getValues();
|
||||
int numSet = 0;
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
|
@ -90,15 +90,15 @@ public class BlockMaskBuilder {
|
||||
charSequence.setString(input);
|
||||
charSequence.setSubstring(0, propStart);
|
||||
|
||||
BlockTypes type = null;
|
||||
List<BlockTypes> blockTypeList = null;
|
||||
BlockType type = null;
|
||||
List<BlockType> blockTypeList = null;
|
||||
if (StringMan.isAlphanumericUnd(charSequence)) {
|
||||
type = BlockTypes.parse(charSequence.toString());
|
||||
add(type);
|
||||
} else {
|
||||
String regex = charSequence.toString();
|
||||
blockTypeList = new ArrayList<>();
|
||||
for (BlockTypes myType : BlockTypes.values) {
|
||||
for (BlockType myType : BlockTypes.values) {
|
||||
if (myType.getId().matches(regex)) {
|
||||
blockTypeList.add(myType);
|
||||
add(myType);
|
||||
@ -135,14 +135,14 @@ public class BlockMaskBuilder {
|
||||
filtered = filterRegexOrOperator(type, key, operator, charSequence);
|
||||
}
|
||||
else {
|
||||
for (BlockTypes myType : blockTypeList) {
|
||||
for (BlockType myType : blockTypeList) {
|
||||
filtered |= filterRegexOrOperator(myType, key, operator, charSequence);
|
||||
}
|
||||
}
|
||||
if (!filtered) {
|
||||
String value = charSequence.toString();
|
||||
final PropertyKey fKey = key;
|
||||
Collection<BlockTypes> types = type != null ? Collections.singleton(type) : blockTypeList;
|
||||
Collection<BlockType> types = type != null ? Collections.singleton(type) : blockTypeList;
|
||||
throw new SuggestInputParseException("No value for " + input, input, () -> {
|
||||
HashSet<String> values = new HashSet<>();
|
||||
types.forEach(t -> {
|
||||
@ -206,7 +206,7 @@ public class BlockMaskBuilder {
|
||||
if (StringMan.isAlphanumericUnd(input)) {
|
||||
add(BlockTypes.parse(input));
|
||||
} else {
|
||||
for (BlockTypes myType : BlockTypes.values) {
|
||||
for (BlockType myType : BlockTypes.values) {
|
||||
if (myType.getId().matches(input)) {
|
||||
add(myType);
|
||||
}
|
||||
@ -225,7 +225,7 @@ public class BlockMaskBuilder {
|
||||
return (states == BlockMask.ALL || FastBitSet.get(states, localI));
|
||||
}
|
||||
|
||||
private void suggest(String input, String property, Collection<BlockTypes> finalTypes) throws InputParseException {
|
||||
private void suggest(String input, String property, Collection<BlockType> finalTypes) throws InputParseException {
|
||||
throw new SuggestInputParseException(input + " does not have: " + property, input, () -> {
|
||||
Set<PropertyKey> keys = new HashSet<>();
|
||||
finalTypes.forEach(t -> t.getProperties().stream().forEach(p -> keys.add(p.getKey())));
|
||||
@ -346,7 +346,7 @@ public class BlockMaskBuilder {
|
||||
bitSets[i] = null;
|
||||
continue;
|
||||
}
|
||||
List<AbstractProperty> properties = (List<AbstractProperty>) type.getProperties();
|
||||
List<AbstractProperty<?>> properties = (List<AbstractProperty<?>>) type.getProperties();
|
||||
for (AbstractProperty prop : properties) {
|
||||
List values = prop.getValues();
|
||||
for (int j = 0; j < values.size(); j++) {
|
||||
@ -425,7 +425,7 @@ public class BlockMaskBuilder {
|
||||
if (!typePredicate.test(type)) {
|
||||
continue;
|
||||
}
|
||||
for (AbstractProperty prop : (List<AbstractProperty>) type.getProperties()) {
|
||||
for (AbstractProperty prop : (List<AbstractProperty<?>>) type.getProperties()) {
|
||||
List values = prop.getValues();
|
||||
for (int j = 0; j < values.size(); j++) {
|
||||
int localI = j << prop.getBitOffset() >> BlockTypes.BIT_OFFSET;
|
||||
@ -533,7 +533,7 @@ public class BlockMaskBuilder {
|
||||
}
|
||||
int set = 0;
|
||||
int clear = 0;
|
||||
for (AbstractProperty prop : (List<AbstractProperty>) type.getProperties()) {
|
||||
for (AbstractProperty prop : (List<AbstractProperty<?>>) type.getProperties()) {
|
||||
List values = prop.getValues();
|
||||
for (int j = 0; j < values.size(); j++) {
|
||||
int localI = j << prop.getBitOffset() >> BlockTypes.BIT_OFFSET;
|
||||
|
@ -4,7 +4,7 @@ package com.sk89q.worldedit.function.mask;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
@ -14,7 +14,7 @@ public class SolidBlockMask extends BlockTypeMask {
|
||||
|
||||
public static boolean[] getTypes() {
|
||||
boolean[] types = new boolean[BlockTypes.size()];
|
||||
for (BlockTypes type : BlockTypes.values) {
|
||||
for (BlockType type : BlockTypes.values) {
|
||||
types[type.getInternalId()] = type.getMaterial().isSolid();
|
||||
}
|
||||
return types;
|
||||
|
@ -90,13 +90,8 @@ public class ForwardExtentCopy implements Operation {
|
||||
* @param source the source extent
|
||||
* @param region the region to copy
|
||||
* @param destination the destination extent
|
||||
<<<<<<< HEAD
|
||||
* @param to the destination position
|
||||
* @see #ForwardExtentCopy(Extent, Region, Vector, Extent, Vector) the main constructor
|
||||
=======
|
||||
* @param to the destination position
|
||||
* @see #ForwardExtentCopy(Extent, Region, BlockVector3, Extent, BlockVector3) the main constructor
|
||||
>>>>>>> 399e0ad5... Refactor vector system to be cleaner
|
||||
*/
|
||||
public ForwardExtentCopy(Extent source, Region region, Extent destination, BlockVector3 to) {
|
||||
this(source, region, region.getMinimumPoint(), destination, to);
|
||||
|
@ -131,6 +131,7 @@ public class PasteBuilder {
|
||||
if (ignoreAirBlocks) {
|
||||
copy.setSourceMask(new ExistingBlockMask(clipboard));
|
||||
}
|
||||
System.out.println("PasteBuilder info: extent: " + extent.toString() + "; copy: " + copy + "; transform: " + transform);
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,13 @@ package com.sk89q.worldedit.util;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A collection of cardinal, ordinal, and secondary-ordinal directions.
|
||||
@ -55,12 +60,9 @@ public enum Direction {
|
||||
private final Vector3 direction;
|
||||
private final BlockVector3 blockVector;
|
||||
private final int flags, left, right;
|
||||
|
||||
|
||||
|
||||
private static HashMap<String, Direction> map = new HashMap<>();
|
||||
public static final Direction[] values = values();
|
||||
public static final Direction[] cardinal = new Direction[]{ NORTH, EAST, SOUTH, WEST };
|
||||
|
||||
|
||||
static {
|
||||
for (Direction dir : Direction.values()) {
|
||||
map.put(dir.name(), dir);
|
||||
@ -68,24 +70,24 @@ public enum Direction {
|
||||
}
|
||||
}
|
||||
|
||||
private Direction(Vector3 vector, int flags, int left, int right) {
|
||||
Direction(Vector3 vector, int flags, int left, int right) {
|
||||
this.direction = vector.normalize();
|
||||
this.blockVector = BlockVector3.at(Math.signum(vector.getX()), Math.signum(vector.getY()), Math.signum(vector.getZ()));
|
||||
this.flags = flags;
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
|
||||
public static Direction get(CharSequence sequence) {
|
||||
return map.get(sequence);
|
||||
}
|
||||
|
||||
|
||||
public Direction getLeft() {
|
||||
return left != -1 ? values[left] : null;
|
||||
return left != -1 ? values()[left] : null;
|
||||
}
|
||||
|
||||
public Direction getRight() {
|
||||
return right != -1 ? values[right] : null;
|
||||
return right != -1 ? values()[right] : null;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
@ -163,11 +165,6 @@ public enum Direction {
|
||||
return direction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the vector.
|
||||
*
|
||||
@ -208,6 +205,110 @@ public enum Direction {
|
||||
return closest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all directions with the given flags.
|
||||
*
|
||||
* @param flags The flags
|
||||
* @return The directions that fit the flags
|
||||
*/
|
||||
public static List<Direction> valuesOf(int flags) {
|
||||
List<Direction> directions = new ArrayList<>();
|
||||
for (Direction direction : values()) {
|
||||
if ((~flags & direction.flags) == 0) {
|
||||
directions.add(direction);
|
||||
}
|
||||
}
|
||||
|
||||
return directions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a rotation index into a Direction.
|
||||
*
|
||||
* <p>
|
||||
* Rotation indexes are used in BlockStates, such as sign posts.
|
||||
* </p>
|
||||
*
|
||||
* @param rotation The rotation index
|
||||
* @return The direction, if applicable
|
||||
*/
|
||||
public static Optional<Direction> fromRotationIndex(int rotation) {
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
return Optional.of(SOUTH);
|
||||
case 1:
|
||||
return Optional.of(SOUTH_SOUTHWEST);
|
||||
case 2:
|
||||
return Optional.of(SOUTHWEST);
|
||||
case 3:
|
||||
return Optional.of(WEST_SOUTHWEST);
|
||||
case 4:
|
||||
return Optional.of(WEST);
|
||||
case 5:
|
||||
return Optional.of(WEST_NORTHWEST);
|
||||
case 6:
|
||||
return Optional.of(NORTHWEST);
|
||||
case 7:
|
||||
return Optional.of(NORTH_NORTHWEST);
|
||||
case 8:
|
||||
return Optional.of(NORTH);
|
||||
case 9:
|
||||
return Optional.of(NORTH_NORTHEAST);
|
||||
case 10:
|
||||
return Optional.of(NORTHEAST);
|
||||
case 11:
|
||||
return Optional.of(EAST_NORTHEAST);
|
||||
case 12:
|
||||
return Optional.of(EAST);
|
||||
case 13:
|
||||
return Optional.of(EAST_SOUTHEAST);
|
||||
case 14:
|
||||
return Optional.of(SOUTHEAST);
|
||||
case 15:
|
||||
return Optional.of(SOUTH_SOUTHEAST);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public OptionalInt toRotationIndex() {
|
||||
switch (this) {
|
||||
case SOUTH:
|
||||
return OptionalInt.of(0);
|
||||
case SOUTH_SOUTHWEST:
|
||||
return OptionalInt.of(1);
|
||||
case SOUTHWEST:
|
||||
return OptionalInt.of(2);
|
||||
case WEST_SOUTHWEST:
|
||||
return OptionalInt.of(3);
|
||||
case WEST:
|
||||
return OptionalInt.of(4);
|
||||
case WEST_NORTHWEST:
|
||||
return OptionalInt.of(5);
|
||||
case NORTHWEST:
|
||||
return OptionalInt.of(6);
|
||||
case NORTH_NORTHWEST:
|
||||
return OptionalInt.of(7);
|
||||
case NORTH:
|
||||
return OptionalInt.of(8);
|
||||
case NORTH_NORTHEAST:
|
||||
return OptionalInt.of(9);
|
||||
case NORTHEAST:
|
||||
return OptionalInt.of(10);
|
||||
case EAST_NORTHEAST:
|
||||
return OptionalInt.of(11);
|
||||
case EAST:
|
||||
return OptionalInt.of(12);
|
||||
case EAST_SOUTHEAST:
|
||||
return OptionalInt.of(13);
|
||||
case SOUTHEAST:
|
||||
return OptionalInt.of(14);
|
||||
case SOUTH_SOUTHEAST:
|
||||
return OptionalInt.of(15);
|
||||
}
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags to use with {@link #findClosest(Vector3, int)}.
|
||||
*/
|
||||
@ -224,4 +325,3 @@ public enum Direction {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -100,14 +100,20 @@ public class PropertiesConfiguration extends LocalConfiguration {
|
||||
logFile = getString("log-file", logFile);
|
||||
logFormat = getString("log-format", logFormat);
|
||||
registerHelp = getBool("register-help", registerHelp);
|
||||
wandItem = ItemTypes.parse(getString("wand-item", wandItem.getId()));
|
||||
wandItem = getString("wand-item", wandItem);
|
||||
try {
|
||||
wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId();
|
||||
} catch (Throwable e) {}
|
||||
superPickaxeDrop = getBool("super-pickaxe-drop-items", superPickaxeDrop);
|
||||
superPickaxeManyDrop = getBool("super-pickaxe-many-drop-items", superPickaxeManyDrop);
|
||||
noDoubleSlash = getBool("no-double-slash", noDoubleSlash);
|
||||
useInventory = getBool("use-inventory", useInventory);
|
||||
useInventoryOverride = getBool("use-inventory-override", useInventoryOverride);
|
||||
useInventoryCreativeOverride = getBool("use-inventory-creative-override", useInventoryCreativeOverride);
|
||||
navigationWand = ItemTypes.parse(getString("navigation-wand.item", navigationWand.getId()));
|
||||
navigationWand = getString("nav-wand-item", navigationWand);
|
||||
try {
|
||||
navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId();
|
||||
} catch (Throwable e) {}
|
||||
navigationWandMaxDistance = getInt("nav-wand-distance", navigationWandMaxDistance);
|
||||
navigationUseGlass = getBool("nav-use-glass", navigationUseGlass);
|
||||
scriptTimeout = getInt("scripting-timeout", scriptTimeout);
|
||||
|
@ -57,7 +57,7 @@ public class YAMLConfiguration extends LocalConfiguration {
|
||||
}
|
||||
|
||||
profile = config.getBoolean("debug", profile);
|
||||
wandItem = ItemTypes.parse(config.getString("wand-item", wandItem.getId()));
|
||||
wandItem = ItemTypes.parse(config.getString("wand-item", wandItem)).getId();
|
||||
|
||||
defaultChangeLimit = Math.max(-1, config.getInt(
|
||||
"limits.max-blocks-changed.default", defaultChangeLimit));
|
||||
@ -105,7 +105,7 @@ public class YAMLConfiguration extends LocalConfiguration {
|
||||
useInventoryCreativeOverride = config.getBoolean("use-inventory.creative-mode-overrides",
|
||||
useInventoryCreativeOverride);
|
||||
|
||||
navigationWand = ItemTypes.parse(config.getString("navigation-wand.item", navigationWand.getId()));
|
||||
navigationWand = ItemTypes.parse(config.getString("navigation-wand.item", navigationWand)).getId();
|
||||
navigationWandMaxDistance = config.getInt("navigation-wand.max-distance", navigationWandMaxDistance);
|
||||
navigationUseGlass = config.getBoolean("navigation.use-glass", navigationUseGlass);
|
||||
|
||||
|
@ -93,7 +93,7 @@ public abstract class AbstractWorld implements World {
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(BlockVector3 position) {
|
||||
return new BaseBlock(getBlock(position));
|
||||
return new BaseBlock(getBlock(position)).toImmutableState();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -59,8 +59,8 @@ public interface SimpleWorld extends World {
|
||||
}
|
||||
|
||||
@Override
|
||||
default BlockState getFullBlock(BlockVector3 position) {
|
||||
return getLazyBlock(position);
|
||||
default BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return getLazyBlock(position).toBaseBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -34,9 +34,15 @@ import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
import com.sk89q.worldedit.blocks.TileEntityBlock;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.SingleBlockStateMask;
|
||||
import com.sk89q.worldedit.function.mask.SingleBlockTypeMask;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@ -48,7 +54,7 @@ import java.util.Objects;
|
||||
* snapshot of blocks correctly, so, for example, the NBT data for a block
|
||||
* may be missing.</p>
|
||||
*/
|
||||
public class BaseBlock extends BlockState {
|
||||
public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
|
||||
private final BlockState blockState;
|
||||
|
||||
@Nullable
|
||||
@ -69,11 +75,6 @@ public class BaseBlock extends BlockState {
|
||||
// this(blockState, blockState.getNbtData());
|
||||
// }
|
||||
|
||||
@Deprecated
|
||||
public BaseBlock(BlockTypes id) {
|
||||
this(id.getDefaultState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a block with the given type and default data.
|
||||
* @deprecated Just use the BlockType.getDefaultState()
|
||||
@ -101,7 +102,6 @@ public class BaseBlock extends BlockState {
|
||||
* @param nbtData NBT data, which must be provided
|
||||
*/
|
||||
public BaseBlock(BlockState state, CompoundTag nbtData) {
|
||||
// super(state.getBlockType());
|
||||
checkNotNull(nbtData);
|
||||
this.blockState = state;
|
||||
this.nbtData = nbtData;
|
||||
@ -145,11 +145,6 @@ public class BaseBlock extends BlockState {
|
||||
this(other.toImmutableState(), other.getNbtData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState toFuzzy() {
|
||||
return blockState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNbtId() {
|
||||
CompoundTag nbtData = getNbtData();
|
||||
@ -181,12 +176,15 @@ public class BaseBlock extends BlockState {
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof BaseBlock)) {
|
||||
if (!hasNbtData() && o instanceof BlockStateHolder) {
|
||||
return Objects.equals(toImmutableState(), ((BlockStateHolder<?>) o).toImmutableState());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
final BaseBlock otherBlock = (BaseBlock) o;
|
||||
|
||||
return this.equals(otherBlock) && Objects.equals(getNbtData(), otherBlock.getNbtData());
|
||||
return this.blockState.equalsFuzzy(otherBlock.blockState) && Objects.equals(getNbtData(), otherBlock.getNbtData());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -205,7 +203,7 @@ public class BaseBlock extends BlockState {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockTypes getBlockType() {
|
||||
public BlockType getBlockType() {
|
||||
return blockState.getBlockType();
|
||||
}
|
||||
|
||||
@ -244,4 +242,65 @@ public class BaseBlock extends BlockState {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNbtData() {
|
||||
return this.nbtData != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockStateHolder withPropertyId(int propertyId) {
|
||||
return getBlockType().withPropertyId(propertyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInternalBlockTypeId() {
|
||||
return toImmutableState().getInternalBlockTypeId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInternalPropertiesId() {
|
||||
return toImmutableState().getInternalPropertiesId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask toMask(Extent extent) {
|
||||
return new SingleBlockStateMask(extent, toImmutableState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> BaseBlock with(Property<V> property, V value) {
|
||||
return toImmutableState().with(property, value).toBaseBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> BlockStateHolder with(PropertyKey property, V value) {
|
||||
return toImmutableState().with(property, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> V getState(Property<V> property) {
|
||||
return toImmutableState().getState(property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> V getState(PropertyKey property) {
|
||||
return toImmutableState().getState(property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Property<?>, Object> getStates() {
|
||||
return toImmutableState().getStates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equalsFuzzy(BlockStateHolder o) {
|
||||
return toImmutableState().equalsFuzzy(o);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.registry.state.AbstractProperty;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
@ -49,13 +50,26 @@ import java.util.stream.Stream;
|
||||
* An immutable class that represents the state a block can be in.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public abstract class BlockState implements BlockStateHolder<BlockState> {
|
||||
public class BlockState implements BlockStateHolder<BlockState> {
|
||||
private final BlockType blockType;
|
||||
private BaseBlock emptyBaseBlock;
|
||||
BlockState(BlockType blockType) {
|
||||
this.blockType = blockType;
|
||||
this.emptyBaseBlock = new BaseBlock(this);
|
||||
}
|
||||
|
||||
BlockState(BlockType blockType, BaseBlock baseBlock){
|
||||
this.blockType = blockType;
|
||||
this.emptyBaseBlock = baseBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a temporary BlockState for a given internal id
|
||||
* @param combinedId
|
||||
* @deprecated magic number
|
||||
* @return BlockState
|
||||
*/
|
||||
|
||||
@Deprecated
|
||||
public static BlockState getFromInternalId(int combinedId) throws InputParseException {
|
||||
return BlockTypes.getFromStateId(combinedId).withStateId(combinedId);
|
||||
@ -85,17 +99,6 @@ public abstract class BlockState implements BlockStateHolder<BlockState> {
|
||||
public static BlockState get(@Nullable BlockType type, String state) throws InputParseException {
|
||||
return get(type, state, null);
|
||||
}
|
||||
// private BlockTypes blockType;
|
||||
// private BaseBlock emptyBaseBlock;
|
||||
|
||||
// Neighbouring state table.
|
||||
private Table<Property<?>, Object, BlockState> states;
|
||||
|
||||
// protected BlockState(BlockTypes blockType) {
|
||||
//// protected BlockState() {
|
||||
// this.blockType = blockType;
|
||||
// this.emptyBaseBlock = new BaseBlock(this);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns a temporary BlockState for a given type and string
|
||||
@ -265,7 +268,7 @@ public abstract class BlockState implements BlockStateHolder<BlockState> {
|
||||
@Override
|
||||
public <V> BlockState with(final Property<V> property, final V value) {
|
||||
try {
|
||||
BlockTypes type = getBlockType();
|
||||
BlockType type = getBlockType();
|
||||
int newState = ((AbstractProperty) property).modify(this.getInternalId(), value);
|
||||
return newState != this.getInternalId() ? type.withStateId(newState) : this;
|
||||
} catch (ClassCastException e) {
|
||||
@ -276,7 +279,7 @@ public abstract class BlockState implements BlockStateHolder<BlockState> {
|
||||
@Override
|
||||
public <V> BlockState with(final PropertyKey property, final V value) {
|
||||
try {
|
||||
BlockTypes type = getBlockType();
|
||||
BlockType type = getBlockType();
|
||||
int newState = ((AbstractProperty) type.getProperty(property)).modify(this.getInternalId(), value);
|
||||
return newState != this.getInternalId() ? type.withStateId(newState) : this;
|
||||
} catch (ClassCastException e) {
|
||||
@ -309,13 +312,10 @@ public abstract class BlockState implements BlockStateHolder<BlockState> {
|
||||
return (Map<Property<?>, Object>) map;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public BaseBlock toBaseBlock() {
|
||||
//// if (this.fuzzy) {
|
||||
//// throw new IllegalArgumentException("Can't create a BaseBlock from a fuzzy BlockState!");
|
||||
//// }
|
||||
// return this.emptyBaseBlock;
|
||||
// }
|
||||
@Override
|
||||
public BaseBlock toBaseBlock() {
|
||||
return this.emptyBaseBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock toBaseBlock(CompoundTag compoundTag) {
|
||||
@ -325,10 +325,10 @@ public abstract class BlockState implements BlockStateHolder<BlockState> {
|
||||
return new BaseBlock(this, compoundTag);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public BlockTypes getBlockType() {
|
||||
// return this.blockType;
|
||||
// }
|
||||
@Override
|
||||
public BlockType getBlockType() {
|
||||
return this.blockType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, use masks - not try to this fuzzy/non fuzzy state nonsense
|
||||
@ -364,4 +364,20 @@ public abstract class BlockState implements BlockStateHolder<BlockState> {
|
||||
public String toString() {
|
||||
return getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInternalId() {
|
||||
return blockType.getInternalId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockMaterial getMaterial() {
|
||||
return blockType.getMaterial();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrdinal() {
|
||||
//?
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public interface BlockStateHolder<T extends BlockStateHolder> extends FawePatter
|
||||
*
|
||||
* @return The type
|
||||
*/
|
||||
BlockTypes getBlockType();
|
||||
BlockType getBlockType();
|
||||
|
||||
/**
|
||||
* Magic number (legacy uses)
|
||||
@ -46,9 +46,7 @@ public interface BlockStateHolder<T extends BlockStateHolder> extends FawePatter
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
default BlockStateHolder withPropertyId(int propertyId) {
|
||||
return getBlockType().withPropertyId(propertyId);
|
||||
}
|
||||
BlockStateHolder withPropertyId(int propertyId);
|
||||
|
||||
/**
|
||||
* Get combined id (legacy uses)
|
||||
@ -60,18 +58,13 @@ public interface BlockStateHolder<T extends BlockStateHolder> extends FawePatter
|
||||
@Deprecated
|
||||
int getOrdinal();
|
||||
|
||||
default BlockMaterial getMaterial() {
|
||||
return getBlockType().getMaterial();
|
||||
}
|
||||
|
||||
BlockMaterial getMaterial();
|
||||
/**
|
||||
* Get type id (legacy uses)
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
default int getInternalBlockTypeId() {
|
||||
return getBlockType().getInternalId();
|
||||
}
|
||||
int getInternalBlockTypeId();
|
||||
|
||||
/**
|
||||
* Get the block data (legacy uses)
|
||||
@ -132,11 +125,7 @@ public interface BlockStateHolder<T extends BlockStateHolder> extends FawePatter
|
||||
boolean equalsFuzzy(BlockStateHolder o);
|
||||
|
||||
/**
|
||||
<<<<<<< HEAD
|
||||
* Returns an immutable BlockStateHolder from this BlockStateHolder.
|
||||
=======
|
||||
* Returns an immutable {@link BlockState} from this BlockStateHolder.
|
||||
>>>>>>> f54d6afb... Make BaseBlock more memory efficient, and make it clear in the API that it's not intended to be used for every single block.
|
||||
*
|
||||
* @return A BlockState
|
||||
*/
|
||||
|
@ -7,12 +7,12 @@ import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
public class BlockStateImpl extends BlockState {
|
||||
private final int internalId;
|
||||
private final int ordinal;
|
||||
private final BlockTypes type;
|
||||
private final BlockType type;
|
||||
private BlockMaterial material;
|
||||
private BaseBlock baseBlock;
|
||||
|
||||
protected BlockStateImpl(BlockTypes type, int internalId, int ordinal) {
|
||||
// super(type);
|
||||
protected BlockStateImpl(BlockType type, int internalId, int ordinal) {
|
||||
super(type);
|
||||
this.type = type;
|
||||
this.internalId = internalId;
|
||||
this.ordinal = ordinal;
|
||||
@ -44,7 +44,7 @@ public class BlockStateImpl extends BlockState {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final BlockTypes getBlockType() {
|
||||
public final BlockType getBlockType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.registry.NamespacedRegistry;
|
||||
import com.sk89q.worldedit.registry.state.AbstractProperty;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
@ -40,30 +41,55 @@ import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public interface BlockType extends FawePattern, Comparable<BlockTypes> {
|
||||
|
||||
default BlockTypes getTypeEnum() {
|
||||
return (BlockTypes) this;
|
||||
}
|
||||
public class BlockType implements FawePattern {
|
||||
|
||||
public static final NamespacedRegistry<BlockType> REGISTRY = new NamespacedRegistry<>("block type");
|
||||
|
||||
private final @Nonnull String id;
|
||||
private ArrayList<BlockState> states;
|
||||
public final Function<BlockState, BlockState> defaultValue;
|
||||
private BlockTypes.Settings settings;
|
||||
private BlockMaterial material;
|
||||
|
||||
public BlockType(@Nonnull String id) {
|
||||
this(id, null);
|
||||
}
|
||||
|
||||
public BlockType(@Nonnull String id, Function<BlockState, BlockState> defaultValue) {
|
||||
this.id = id;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public void setStates(ArrayList<BlockState> states) {
|
||||
this.states = states;
|
||||
}
|
||||
|
||||
public void setSettings(BlockTypes.Settings settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public BlockTypes.Settings getSettings(){
|
||||
return settings;
|
||||
}
|
||||
|
||||
public ArrayList<BlockState> updateStates(){
|
||||
if(settings != null) {
|
||||
return settings.localStates = new ArrayList<BlockState>(settings.localStates.stream().map(state -> new BlockStateImpl(this, state.getInternalId(), state.getOrdinal())).collect(Collectors.toList()));
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
int getMaxStateId();
|
||||
|
||||
@Override
|
||||
default boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
|
||||
return extent.setBlock(set, this.getDefaultState());
|
||||
}
|
||||
|
||||
@Override
|
||||
default BlockStateHolder apply(BlockVector3 position) {
|
||||
return this.getDefaultState();
|
||||
}
|
||||
|
||||
default Mask toMask(Extent extent) {
|
||||
return new SingleBlockTypeMask(extent, this);
|
||||
public int getMaxStateId() {
|
||||
return settings.permutations;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,15 +97,17 @@ public interface BlockType extends FawePattern, Comparable<BlockTypes> {
|
||||
*
|
||||
* @return The id
|
||||
*/
|
||||
String getId();
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
default String getNamespace() {
|
||||
public String getNamespace() {
|
||||
String id = getId();
|
||||
int i = id.indexOf(':');
|
||||
return i == -1 ? "minecraft" : id.substring(0, i);
|
||||
}
|
||||
|
||||
default String getResource() {
|
||||
public String getResource() {
|
||||
String id = getId();
|
||||
return id.substring(id.indexOf(':') + 1);
|
||||
}
|
||||
@ -89,7 +117,7 @@ public interface BlockType extends FawePattern, Comparable<BlockTypes> {
|
||||
*
|
||||
* @return The name, or ID
|
||||
*/
|
||||
default String getName() {
|
||||
public String getName() {
|
||||
BundledBlockData.BlockEntry entry = BundledBlockData.getInstance().findById(this.getId());
|
||||
if (entry == null) {
|
||||
return getId();
|
||||
@ -99,28 +127,41 @@ public interface BlockType extends FawePattern, Comparable<BlockTypes> {
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
default BlockState withPropertyId(int internalPropertiesId) {
|
||||
if (internalPropertiesId == 0) return getDefaultState();
|
||||
return BlockState.getFromInternalId(getInternalId() + (internalPropertiesId << BlockTypes.BIT_OFFSET));
|
||||
public BlockState withPropertyId(int propertyId) {
|
||||
if (settings.stateOrdinals == null) return settings.defaultState;
|
||||
return states.get(settings.stateOrdinals[propertyId]);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public BlockState withStateId(int internalStateId) {
|
||||
return this.withPropertyId(internalStateId >> BlockTypes.BIT_OFFSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties of this BlockType in a {@code key->property} mapping.
|
||||
* Properties string in the form property1=foo,prop2=bar
|
||||
* @param properties
|
||||
* @return
|
||||
*/
|
||||
public BlockState withProperties(String properties) {
|
||||
int id = getInternalId();
|
||||
for (String keyPair : properties.split(",")) {
|
||||
String[] split = keyPair.split("=");
|
||||
String name = split[0];
|
||||
String value = split[1];
|
||||
AbstractProperty btp = settings.propertiesMap.get(name);
|
||||
id = btp.modify(id, btp.getValueFor(value));
|
||||
}
|
||||
return withStateId(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties of this BlockType in a key->property mapping.
|
||||
*
|
||||
* @return The properties map
|
||||
*/
|
||||
@Deprecated
|
||||
default Map<String, ? extends Property> getPropertyMap() {
|
||||
List<? extends Property> properties = getProperties();
|
||||
if (properties.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Map<String, Property> map = new HashMap<>(properties.size());
|
||||
for (Property property : properties) {
|
||||
map.put(property.getName(), property);
|
||||
}
|
||||
return map;
|
||||
public Map<String, ? extends Property<?>> getPropertyMap() {
|
||||
return this.settings.propertiesMap;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,11 +170,13 @@ public interface BlockType extends FawePattern, Comparable<BlockTypes> {
|
||||
* @return the properties
|
||||
*/
|
||||
@Deprecated
|
||||
List<? extends Property> getProperties();
|
||||
public List<? extends Property<?>> getProperties() {
|
||||
return this.settings.propertiesList;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
default Set<? extends Property> getPropertiesSet() {
|
||||
return new HashSet<>(getProperties());
|
||||
public Set<? extends Property<?>> getPropertiesSet() {
|
||||
return this.settings.propertiesSet;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,20 +186,22 @@ public interface BlockType extends FawePattern, Comparable<BlockTypes> {
|
||||
* @return The property
|
||||
*/
|
||||
@Deprecated
|
||||
default <V> Property<V> getProperty(String name) {
|
||||
Property<V> property = getPropertyMap().get(name);
|
||||
checkArgument(property != null, "%s has no property named %s", this, name);
|
||||
return property;
|
||||
public <V> Property<V> getProperty(String name) {
|
||||
checkArgument(this.settings.propertiesMap.get(name) != null, "%s has no property named %s", this, name);
|
||||
return (Property<V>) this.settings.propertiesMap.get(name);
|
||||
}
|
||||
|
||||
default boolean hasProperty(PropertyKey key) {
|
||||
return getPropertyMap().containsKey(key.getId());
|
||||
public boolean hasProperty(PropertyKey key) {
|
||||
int ordinal = key.ordinal();
|
||||
return this.settings.propertiesMapArr.length > ordinal ? this.settings.propertiesMapArr[ordinal] != null : false;
|
||||
}
|
||||
|
||||
default <V> Property<V> getProperty(PropertyKey key) {
|
||||
Property<V> property = getPropertyMap().get(key.getId());
|
||||
checkArgument(property != null, "%s has no property named %s", this, key.getId());
|
||||
return property;
|
||||
|
||||
public <V> Property<V> getProperty(PropertyKey key) {
|
||||
try {
|
||||
return (Property<V>) this.settings.propertiesMapArr[key.ordinal()];
|
||||
} catch (IndexOutOfBoundsException ignore) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,28 +209,54 @@ public interface BlockType extends FawePattern, Comparable<BlockTypes> {
|
||||
*
|
||||
* @return The default state
|
||||
*/
|
||||
BlockState getDefaultState();
|
||||
public BlockState getDefaultState() {
|
||||
BlockState defaultState = this.settings.defaultState;
|
||||
if (defaultValue != null) {
|
||||
defaultState = defaultValue.apply(defaultState);
|
||||
}
|
||||
return defaultState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of all possible states for this BlockType.
|
||||
*
|
||||
* @return All possible states
|
||||
* Slow
|
||||
* @return collection of states
|
||||
*/
|
||||
List<BlockState> getAllStates();
|
||||
@Deprecated
|
||||
public List<BlockState> getAllStates() {
|
||||
if (settings.stateOrdinals == null) return Collections.singletonList(getDefaultState());
|
||||
return IntStream.of(settings.stateOrdinals).filter(i -> i != -1).mapToObj(i -> states.get(i)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a state of this BlockType with the given properties.
|
||||
*
|
||||
* @return The state, if it exists
|
||||
*/
|
||||
BlockState getState(Map<Property<?>, Object> key);
|
||||
public BlockState getState(Map<Property<?>, Object> key) {
|
||||
int id = getInternalId();
|
||||
for (Map.Entry<Property<?>, Object> iter : key.entrySet()) {
|
||||
Property<?> prop = iter.getKey();
|
||||
Object value = iter.getValue();
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* This is likely wrong. The only place this seems to currently (Dec 23 2018)
|
||||
* be invoked is via ForgeWorld, and value is a String when invoked there...
|
||||
*/
|
||||
AbstractProperty btp = this.settings.propertiesMap.get(prop.getName());
|
||||
checkArgument(btp != null, "%s has no property named %s", this, prop.getName());
|
||||
id = btp.modify(id, btp.getValueFor((String)value));
|
||||
}
|
||||
return withStateId(id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets whether this block type has an item representation.
|
||||
*
|
||||
* @return If it has an item
|
||||
*/
|
||||
default boolean hasItemType() {
|
||||
public boolean hasItemType() {
|
||||
return getItemType() != null;
|
||||
}
|
||||
|
||||
@ -195,8 +266,8 @@ public interface BlockType extends FawePattern, Comparable<BlockTypes> {
|
||||
* @return The item representation
|
||||
*/
|
||||
@Nullable
|
||||
default ItemType getItemType() {
|
||||
return ItemTypes.get(this.getTypeEnum());
|
||||
public ItemType getItemType() {
|
||||
return ItemTypes.get(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -204,7 +275,11 @@ public interface BlockType extends FawePattern, Comparable<BlockTypes> {
|
||||
*
|
||||
* @return The material
|
||||
*/
|
||||
BlockMaterial getMaterial();
|
||||
public BlockMaterial getMaterial() {
|
||||
return this.material == null ?
|
||||
WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this)
|
||||
: this.material;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the legacy ID. Needed for legacy reasons.
|
||||
@ -213,7 +288,7 @@ public interface BlockType extends FawePattern, Comparable<BlockTypes> {
|
||||
*
|
||||
* @return legacy id or 0, if unknown
|
||||
*/
|
||||
default int getLegacyCombinedId() {
|
||||
public int getLegacyCombinedId() {
|
||||
Integer combinedId = LegacyMapper.getInstance().getLegacyCombined(this);
|
||||
return combinedId == null ? 0 : combinedId;
|
||||
}
|
||||
@ -225,16 +300,43 @@ public interface BlockType extends FawePattern, Comparable<BlockTypes> {
|
||||
*
|
||||
* @return internal id
|
||||
*/
|
||||
int getInternalId();
|
||||
public int getInternalId() {
|
||||
return this.settings.internalId;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean equals(Object obj);
|
||||
public int hashCode() {
|
||||
return this.id.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
int hashCode();
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof BlockType && this.id.equals(((BlockType) obj).id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getId();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException {
|
||||
return extent.setBlock(set, this.getDefaultState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockStateHolder apply(BlockVector3 position) {
|
||||
return this.getDefaultState();
|
||||
}
|
||||
|
||||
public Mask toMask(Extent extent) {
|
||||
return new SingleBlockTypeMask(extent, this);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
default int getLegacyId() {
|
||||
public int getLegacyId() {
|
||||
Integer id = LegacyMapper.getInstance().getLegacyCombined(this.getDefaultState());
|
||||
if (id != null) {
|
||||
return id >> 4;
|
||||
|
@ -17,7 +17,7 @@ public class BlockTypeSwitchBuilder<T> {
|
||||
}
|
||||
|
||||
public BlockTypeSwitchBuilder<T> add(Predicate<BlockType> predicate, T task) {
|
||||
for (BlockTypes type : BlockTypes.values) {
|
||||
for (BlockType type : BlockTypes.values) {
|
||||
if (predicate.test(type)) {
|
||||
this.runnables[type.getInternalId()] = task;
|
||||
}
|
||||
|
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* 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.world.block;
|
||||
|
||||
import com.sk89q.worldedit.registry.state.PropertyGroup;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class BlockTypeUtil {
|
||||
|
||||
public static double centralTopLimit(com.sk89q.worldedit.world.block.BlockType type) {
|
||||
checkNotNull(type);
|
||||
return centralTopLimit(type.getDefaultState());
|
||||
}
|
||||
|
||||
public static double centralBottomLimit(BlockStateHolder block) {
|
||||
checkNotNull(block);
|
||||
BlockType type = block.getBlockType();
|
||||
switch (type.getResource().toUpperCase()) {
|
||||
case "CREEPER_WALL_HEAD":
|
||||
case "DRAGON_WALL_HEAD":
|
||||
case "PLAYER_WALL_HEAD":
|
||||
case "ZOMBIE_WALL_HEAD": return 0.25;
|
||||
case "ACACIA_SLAB":
|
||||
case "BIRCH_SLAB":
|
||||
case "BRICK_SLAB":
|
||||
case "COBBLESTONE_SLAB":
|
||||
case "DARK_OAK_SLAB":
|
||||
case "DARK_PRISMARINE_SLAB":
|
||||
case "JUNGLE_SLAB":
|
||||
case "NETHER_BRICK_SLAB":
|
||||
case "OAK_SLAB":
|
||||
case "PETRIFIED_OAK_SLAB":
|
||||
case "PRISMARINE_BRICK_SLAB":
|
||||
case "PRISMARINE_SLAB":
|
||||
case "PURPUR_SLAB":
|
||||
case "QUARTZ_SLAB":
|
||||
case "RED_SANDSTONE_SLAB":
|
||||
case "SANDSTONE_SLAB":
|
||||
case "SPRUCE_SLAB":
|
||||
case "STONE_BRICK_SLAB":
|
||||
case "STONE_SLAB": {
|
||||
String state = (String) block.getState(PropertyKey.TYPE);
|
||||
if (state == null) return 0;
|
||||
switch (state) {
|
||||
case "double":
|
||||
case "bottom":
|
||||
return 0;
|
||||
case "top":
|
||||
return 0.5;
|
||||
}
|
||||
}
|
||||
case "ACACIA_TRAPDOOR":
|
||||
case "BIRCH_TRAPDOOR":
|
||||
case "DARK_OAK_TRAPDOOR":
|
||||
case "IRON_TRAPDOOR":
|
||||
case "JUNGLE_TRAPDOOR":
|
||||
case "OAK_TRAPDOOR":
|
||||
case "SPRUCE_TRAPDOOR":
|
||||
if (block.getState(PropertyKey.OPEN) == Boolean.TRUE) {
|
||||
return 1;
|
||||
} else if ("bottom".equals(block.getState(PropertyKey.HALF))) {
|
||||
return 0.8125;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
case "ACACIA_FENCE_GATE":
|
||||
case "BIRCH_FENCE_GATE":
|
||||
case "DARK_OAK_FENCE_GATE":
|
||||
case "JUNGLE_FENCE_GATE":
|
||||
case "OAK_FENCE_GATE":
|
||||
case "SPRUCE_FENCE_GATE": return block.getState(PropertyKey.OPEN) == Boolean.TRUE ? 1 : 0;
|
||||
default:
|
||||
if (type.getMaterial().isMovementBlocker()) return 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the y offset a player falls to when falling onto the top of a block at xp+0.5/zp+0.5.
|
||||
*
|
||||
* @param block the block
|
||||
* @return the y offset
|
||||
*/
|
||||
public static double centralTopLimit(BlockStateHolder block) {
|
||||
checkNotNull(block);
|
||||
BlockType type = block.getBlockType();
|
||||
switch (type.getResource().toUpperCase()) {
|
||||
case "BLACK_BED":
|
||||
case "BLUE_BED":
|
||||
case "BROWN_BED":
|
||||
case "CYAN_BED":
|
||||
case "GRAY_BED":
|
||||
case "GREEN_BED":
|
||||
case "LIGHT_BLUE_BED":
|
||||
case "LIGHT_GRAY_BED":
|
||||
case "LIME_BED":
|
||||
case "MAGENTA_BED":
|
||||
case "ORANGE_BED":
|
||||
case "PINK_BED":
|
||||
case "PURPLE_BED":
|
||||
case "RED_BED":
|
||||
case "WHITE_BED":
|
||||
case "YELLOW_BED": return 0.5625;
|
||||
case "BREWING_STAND": return 0.875;
|
||||
case "CAKE": return (block.getState(PropertyKey.BITES) == (Integer) 6) ? 0 : 0.4375;
|
||||
case "CAULDRON": return 0.3125;
|
||||
case "COCOA": return 0.750;
|
||||
case "ENCHANTING_TABLE": return 0.75;
|
||||
case "END_PORTAL_FRAME": return block.getState(PropertyKey.EYE) == Boolean.TRUE ? 1 : 0.8125;
|
||||
case "CREEPER_HEAD":
|
||||
case "DRAGON_HEAD":
|
||||
case "PISTON_HEAD":
|
||||
case "PLAYER_HEAD":
|
||||
case "ZOMBIE_HEAD": return 0.5;
|
||||
case "CREEPER_WALL_HEAD":
|
||||
case "DRAGON_WALL_HEAD":
|
||||
case "PLAYER_WALL_HEAD":
|
||||
case "ZOMBIE_WALL_HEAD": return 0.75;
|
||||
case "ACACIA_FENCE":
|
||||
case "BIRCH_FENCE":
|
||||
case "DARK_OAK_FENCE":
|
||||
case "JUNGLE_FENCE":
|
||||
case "NETHER_BRICK_FENCE":
|
||||
case "OAK_FENCE":
|
||||
case "SPRUCE_FENCE": return 1.5;
|
||||
case "ACACIA_SLAB":
|
||||
case "BIRCH_SLAB":
|
||||
case "BRICK_SLAB":
|
||||
case "COBBLESTONE_SLAB":
|
||||
case "DARK_OAK_SLAB":
|
||||
case "DARK_PRISMARINE_SLAB":
|
||||
case "JUNGLE_SLAB":
|
||||
case "NETHER_BRICK_SLAB":
|
||||
case "OAK_SLAB":
|
||||
case "PETRIFIED_OAK_SLAB":
|
||||
case "PRISMARINE_BRICK_SLAB":
|
||||
case "PRISMARINE_SLAB":
|
||||
case "PURPUR_SLAB":
|
||||
case "QUARTZ_SLAB":
|
||||
case "RED_SANDSTONE_SLAB":
|
||||
case "SANDSTONE_SLAB":
|
||||
case "SPRUCE_SLAB":
|
||||
case "STONE_BRICK_SLAB":
|
||||
case "STONE_SLAB": {
|
||||
String state = (String) block.getState(PropertyKey.TYPE);
|
||||
if (state == null) return 0.5;
|
||||
switch (state) {
|
||||
case "bottom":
|
||||
return 0.5;
|
||||
case "top":
|
||||
case "double":
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
case "LILY_PAD": return 0.015625;
|
||||
case "REPEATER": return 0.125;
|
||||
case "SOUL_SAND": return 0.875;
|
||||
case "COBBLESTONE_WALL":
|
||||
case "MOSSY_COBBLESTONE_WALL": return 1.5;
|
||||
case "FLOWER_POT": return 0.375;
|
||||
case "COMPARATOR": return 0.125;
|
||||
case "DAYLIGHT_DETECTOR": return 0.375;
|
||||
case "HOPPER": return 0.625;
|
||||
case "ACACIA_TRAPDOOR":
|
||||
case "BIRCH_TRAPDOOR":
|
||||
case "DARK_OAK_TRAPDOOR":
|
||||
case "IRON_TRAPDOOR":
|
||||
case "JUNGLE_TRAPDOOR":
|
||||
case "OAK_TRAPDOOR":
|
||||
case "SPRUCE_TRAPDOOR":
|
||||
if (block.getState(PropertyKey.OPEN) == Boolean.TRUE) {
|
||||
return 0;
|
||||
} else if ("top".equals(block.getState(PropertyKey.HALF))) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0.1875;
|
||||
}
|
||||
case "ACACIA_FENCE_GATE":
|
||||
case "BIRCH_FENCE_GATE":
|
||||
case "DARK_OAK_FENCE_GATE":
|
||||
case "JUNGLE_FENCE_GATE":
|
||||
case "OAK_FENCE_GATE":
|
||||
case "SPRUCE_FENCE_GATE": return block.getState(PropertyKey.OPEN) == Boolean.TRUE ? 0 : 1.5;
|
||||
default:
|
||||
if (type.hasProperty(PropertyKey.LAYERS)) {
|
||||
return PropertyGroup.LEVEL.get(block) * 0.0625;
|
||||
}
|
||||
if (!type.getMaterial().isMovementBlocker()) return 0;
|
||||
return 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -21,18 +21,46 @@ package com.sk89q.worldedit.world.entity;
|
||||
|
||||
import com.sk89q.worldedit.registry.NamespacedRegistry;
|
||||
|
||||
public interface EntityType {
|
||||
String getId();
|
||||
public class EntityType {
|
||||
|
||||
public static final NamespacedRegistry<EntityType> REGISTRY = new NamespacedRegistry<>("entity type");
|
||||
|
||||
private String id;
|
||||
|
||||
public EntityType(String id) {
|
||||
// If it has no namespace, assume minecraft.
|
||||
if (!id.contains(":")) {
|
||||
id = "minecraft:" + id;
|
||||
}
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this item, or the ID if the name cannot be found.
|
||||
*
|
||||
* @return The name, or ID
|
||||
*/
|
||||
default String getName() {
|
||||
public String getName() {
|
||||
return getId();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int getInternalId();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.id.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof EntityType && this.id.equals(((EntityType) obj).id);
|
||||
}
|
||||
|
||||
}
|
@ -19,166 +19,121 @@
|
||||
|
||||
package com.sk89q.worldedit.world.entity;
|
||||
|
||||
import com.boydti.fawe.util.ReflectionUtils;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
public enum EntityTypes implements EntityType {
|
||||
/*
|
||||
-----------------------------------------------------
|
||||
Replaced at runtime by the entity registry
|
||||
-----------------------------------------------------
|
||||
*/
|
||||
__RESERVED__,
|
||||
AREA_EFFECT_CLOUD,
|
||||
ARMOR_STAND,
|
||||
ARROW,
|
||||
BAT,
|
||||
BLAZE,
|
||||
BOAT,
|
||||
CAVE_SPIDER,
|
||||
CHEST_MINECART,
|
||||
CHICKEN,
|
||||
COD,
|
||||
COMMAND_BLOCK_MINECART,
|
||||
COW,
|
||||
CREEPER,
|
||||
DOLPHIN,
|
||||
DONKEY,
|
||||
DRAGON_FIREBALL,
|
||||
DROWNED,
|
||||
EGG,
|
||||
ELDER_GUARDIAN,
|
||||
END_CRYSTAL,
|
||||
ENDER_DRAGON,
|
||||
ENDER_PEARL,
|
||||
ENDERMAN,
|
||||
ENDERMITE,
|
||||
EVOKER,
|
||||
EVOKER_FANGS,
|
||||
EXPERIENCE_BOTTLE,
|
||||
EXPERIENCE_ORB,
|
||||
EYE_OF_ENDER,
|
||||
FALLING_BLOCK,
|
||||
FIREBALL,
|
||||
FIREWORK_ROCKET,
|
||||
FISHING_BOBBER,
|
||||
FURNACE_MINECART,
|
||||
GHAST,
|
||||
GIANT,
|
||||
GUARDIAN,
|
||||
HOPPER_MINECART,
|
||||
HORSE,
|
||||
HUSK,
|
||||
ILLUSIONER,
|
||||
IRON_GOLEM,
|
||||
ITEM,
|
||||
ITEM_FRAME,
|
||||
LEASH_KNOT,
|
||||
LIGHTNING_BOLT,
|
||||
LLAMA,
|
||||
LLAMA_SPIT,
|
||||
MAGMA_CUBE,
|
||||
MINECART,
|
||||
MOOSHROOM,
|
||||
MULE,
|
||||
OCELOT,
|
||||
PAINTING,
|
||||
PARROT,
|
||||
PHANTOM,
|
||||
PIG,
|
||||
PLAYER,
|
||||
POLAR_BEAR,
|
||||
POTION,
|
||||
PUFFERFISH,
|
||||
RABBIT,
|
||||
SALMON,
|
||||
SHEEP,
|
||||
SHULKER,
|
||||
SHULKER_BULLET,
|
||||
SILVERFISH,
|
||||
SKELETON,
|
||||
SKELETON_HORSE,
|
||||
SLIME,
|
||||
SMALL_FIREBALL,
|
||||
SNOW_GOLEM,
|
||||
SNOWBALL,
|
||||
SPAWNER_MINECART,
|
||||
SPECTRAL_ARROW,
|
||||
SPIDER,
|
||||
SQUID,
|
||||
STRAY,
|
||||
TNT,
|
||||
TNT_MINECART,
|
||||
TRIDENT,
|
||||
TROPICAL_FISH,
|
||||
TURTLE,
|
||||
VEX,
|
||||
VILLAGER,
|
||||
VINDICATOR,
|
||||
WITCH,
|
||||
WITHER,
|
||||
WITHER_SKELETON,
|
||||
WITHER_SKULL,
|
||||
WOLF,
|
||||
ZOMBIE,
|
||||
ZOMBIE_HORSE,
|
||||
ZOMBIE_PIGMAN,
|
||||
ZOMBIE_VILLAGER,
|
||||
public class EntityTypes {
|
||||
|
||||
;
|
||||
public static final EntityType AREA_EFFECT_CLOUD = register("minecraft:area_effect_cloud");
|
||||
public static final EntityType ARMOR_STAND = register("minecraft:armor_stand");
|
||||
public static final EntityType ARROW = register("minecraft:arrow");
|
||||
public static final EntityType BAT = register("minecraft:bat");
|
||||
public static final EntityType BLAZE = register("minecraft:blaze");
|
||||
public static final EntityType BOAT = register("minecraft:boat");
|
||||
public static final EntityType CAVE_SPIDER = register("minecraft:cave_spider");
|
||||
public static final EntityType CHEST_MINECART = register("minecraft:chest_minecart");
|
||||
public static final EntityType CHICKEN = register("minecraft:chicken");
|
||||
public static final EntityType COD = register("minecraft:cod");
|
||||
public static final EntityType COMMAND_BLOCK_MINECART = register("minecraft:command_block_minecart");
|
||||
public static final EntityType COW = register("minecraft:cow");
|
||||
public static final EntityType CREEPER = register("minecraft:creeper");
|
||||
public static final EntityType DOLPHIN = register("minecraft:dolphin");
|
||||
public static final EntityType DONKEY = register("minecraft:donkey");
|
||||
public static final EntityType DRAGON_FIREBALL = register("minecraft:dragon_fireball");
|
||||
public static final EntityType DROWNED = register("minecraft:drowned");
|
||||
public static final EntityType EGG = register("minecraft:egg");
|
||||
public static final EntityType ELDER_GUARDIAN = register("minecraft:elder_guardian");
|
||||
public static final EntityType END_CRYSTAL = register("minecraft:end_crystal");
|
||||
public static final EntityType ENDER_DRAGON = register("minecraft:ender_dragon");
|
||||
public static final EntityType ENDER_PEARL = register("minecraft:ender_pearl");
|
||||
public static final EntityType ENDERMAN = register("minecraft:enderman");
|
||||
public static final EntityType ENDERMITE = register("minecraft:endermite");
|
||||
public static final EntityType EVOKER = register("minecraft:evoker");
|
||||
public static final EntityType EVOKER_FANGS = register("minecraft:evoker_fangs");
|
||||
public static final EntityType EXPERIENCE_BOTTLE = register("minecraft:experience_bottle");
|
||||
public static final EntityType EXPERIENCE_ORB = register("minecraft:experience_orb");
|
||||
public static final EntityType EYE_OF_ENDER = register("minecraft:eye_of_ender");
|
||||
public static final EntityType FALLING_BLOCK = register("minecraft:falling_block");
|
||||
public static final EntityType FIREBALL = register("minecraft:fireball");
|
||||
public static final EntityType FIREWORK_ROCKET = register("minecraft:firework_rocket");
|
||||
public static final EntityType FISHING_BOBBER = register("minecraft:fishing_bobber");
|
||||
public static final EntityType FURNACE_MINECART = register("minecraft:furnace_minecart");
|
||||
public static final EntityType GHAST = register("minecraft:ghast");
|
||||
public static final EntityType GIANT = register("minecraft:giant");
|
||||
public static final EntityType GUARDIAN = register("minecraft:guardian");
|
||||
public static final EntityType HOPPER_MINECART = register("minecraft:hopper_minecart");
|
||||
public static final EntityType HORSE = register("minecraft:horse");
|
||||
public static final EntityType HUSK = register("minecraft:husk");
|
||||
public static final EntityType ILLUSIONER = register("minecraft:illusioner");
|
||||
public static final EntityType IRON_GOLEM = register("minecraft:iron_golem");
|
||||
public static final EntityType ITEM = register("minecraft:item");
|
||||
public static final EntityType ITEM_FRAME = register("minecraft:item_frame");
|
||||
public static final EntityType LEASH_KNOT = register("minecraft:leash_knot");
|
||||
public static final EntityType LIGHTNING_BOLT = register("minecraft:lightning_bolt");
|
||||
public static final EntityType LLAMA = register("minecraft:llama");
|
||||
public static final EntityType LLAMA_SPIT = register("minecraft:llama_spit");
|
||||
public static final EntityType MAGMA_CUBE = register("minecraft:magma_cube");
|
||||
public static final EntityType MINECART = register("minecraft:minecart");
|
||||
public static final EntityType MOOSHROOM = register("minecraft:mooshroom");
|
||||
public static final EntityType MULE = register("minecraft:mule");
|
||||
public static final EntityType OCELOT = register("minecraft:ocelot");
|
||||
public static final EntityType PAINTING = register("minecraft:painting");
|
||||
public static final EntityType PARROT = register("minecraft:parrot");
|
||||
public static final EntityType PHANTOM = register("minecraft:phantom");
|
||||
public static final EntityType PIG = register("minecraft:pig");
|
||||
public static final EntityType PLAYER = register("minecraft:player");
|
||||
public static final EntityType POLAR_BEAR = register("minecraft:polar_bear");
|
||||
public static final EntityType POTION = register("minecraft:potion");
|
||||
public static final EntityType PUFFERFISH = register("minecraft:pufferfish");
|
||||
public static final EntityType RABBIT = register("minecraft:rabbit");
|
||||
public static final EntityType SALMON = register("minecraft:salmon");
|
||||
public static final EntityType SHEEP = register("minecraft:sheep");
|
||||
public static final EntityType SHULKER = register("minecraft:shulker");
|
||||
public static final EntityType SHULKER_BULLET = register("minecraft:shulker_bullet");
|
||||
public static final EntityType SILVERFISH = register("minecraft:silverfish");
|
||||
public static final EntityType SKELETON = register("minecraft:skeleton");
|
||||
public static final EntityType SKELETON_HORSE = register("minecraft:skeleton_horse");
|
||||
public static final EntityType SLIME = register("minecraft:slime");
|
||||
public static final EntityType SMALL_FIREBALL = register("minecraft:small_fireball");
|
||||
public static final EntityType SNOW_GOLEM = register("minecraft:snow_golem");
|
||||
public static final EntityType SNOWBALL = register("minecraft:snowball");
|
||||
public static final EntityType SPAWNER_MINECART = register("minecraft:spawner_minecart");
|
||||
public static final EntityType SPECTRAL_ARROW = register("minecraft:spectral_arrow");
|
||||
public static final EntityType SPIDER = register("minecraft:spider");
|
||||
public static final EntityType SQUID = register("minecraft:squid");
|
||||
public static final EntityType STRAY = register("minecraft:stray");
|
||||
public static final EntityType TNT = register("minecraft:tnt");
|
||||
public static final EntityType TNT_MINECART = register("minecraft:tnt_minecart");
|
||||
public static final EntityType TRIDENT = register("minecraft:trident");
|
||||
public static final EntityType TROPICAL_FISH = register("minecraft:tropical_fish");
|
||||
public static final EntityType TURTLE = register("minecraft:turtle");
|
||||
public static final EntityType VEX = register("minecraft:vex");
|
||||
public static final EntityType VILLAGER = register("minecraft:villager");
|
||||
public static final EntityType VINDICATOR = register("minecraft:vindicator");
|
||||
public static final EntityType WITCH = register("minecraft:witch");
|
||||
public static final EntityType WITHER = register("minecraft:wither");
|
||||
public static final EntityType WITHER_SKELETON = register("minecraft:wither_skeleton");
|
||||
public static final EntityType WITHER_SKULL = register("minecraft:wither_skull");
|
||||
public static final EntityType WOLF = register("minecraft:wolf");
|
||||
public static final EntityType ZOMBIE = register("minecraft:zombie");
|
||||
public static final EntityType ZOMBIE_HORSE = register("minecraft:zombie_horse");
|
||||
public static final EntityType ZOMBIE_PIGMAN = register("minecraft:zombie_pigman");
|
||||
public static final EntityType ZOMBIE_VILLAGER = register("minecraft:zombie_villager");
|
||||
|
||||
private String id;
|
||||
private int internalId;
|
||||
|
||||
EntityTypes() {
|
||||
this(null);
|
||||
private EntityTypes() {
|
||||
}
|
||||
|
||||
EntityTypes(String id) {
|
||||
init(id);
|
||||
private static EntityType register(final String id) {
|
||||
return register(new EntityType(id));
|
||||
}
|
||||
|
||||
private void init(String id) {
|
||||
if (id == null) id = "minecraft:" + name().toLowerCase();
|
||||
// If it has no namespace, assume minecraft.
|
||||
else if (!id.contains(":")) {
|
||||
id = "minecraft:" + id;
|
||||
}
|
||||
this.id = id;
|
||||
this.internalId = ordinal();
|
||||
public static EntityType register(final EntityType entityType) {
|
||||
return EntityType.REGISTRY.register(entityType.getId(), entityType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
public static @Nullable EntityType get(final String id) {
|
||||
return EntityType.REGISTRY.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInternalId() {
|
||||
return internalId;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------
|
||||
Static Initializer
|
||||
-----------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
public static EntityType parse(String id) {
|
||||
if (id.startsWith("minecraft:")) id = id.substring(10);
|
||||
switch (id) {
|
||||
@ -246,64 +201,4 @@ public enum EntityTypes implements EntityType {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<String, EntityTypes> $REGISTRY = new HashMap<>();
|
||||
private static int $LENGTH;
|
||||
public static final EntityTypes[] values;
|
||||
|
||||
static {
|
||||
try {
|
||||
Collection<String> ents = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getEntityRegistry().registerEntities();
|
||||
EntityTypes[] oldValues = values();
|
||||
$LENGTH = oldValues.length;
|
||||
LinkedHashSet<EntityTypes> newValues = new LinkedHashSet<>(Arrays.asList(oldValues));
|
||||
if (!ents.isEmpty()) { // No types found - use defaults
|
||||
for (String ent : ents) {
|
||||
EntityTypes registered = register(ent);
|
||||
if (!newValues.contains(registered)) newValues.add(registered);
|
||||
}
|
||||
}
|
||||
// Cache the values
|
||||
values = newValues.toArray(new EntityTypes[newValues.size()]);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static EntityTypes register(final String id) {
|
||||
// Get the enum name (remove namespace if minecraft:)
|
||||
int propStart = id.indexOf('[');
|
||||
String typeName = id.substring(0, propStart == -1 ? id.length() : propStart);
|
||||
String enumName = (typeName.startsWith("minecraft:") ? typeName.substring(10) : typeName).toUpperCase();
|
||||
// Check existing
|
||||
EntityTypes existing = null;
|
||||
try { existing = valueOf(enumName.toUpperCase()); } catch (IllegalArgumentException ignore) {}
|
||||
if (existing == null) {
|
||||
existing = ReflectionUtils.addEnum(EntityTypes.class, enumName);
|
||||
}
|
||||
int internalId = existing.ordinal();
|
||||
if (existing.id == null) {
|
||||
existing.init(null);
|
||||
}
|
||||
if (internalId == 0 && existing != __RESERVED__) {
|
||||
existing.internalId = $LENGTH++;
|
||||
}
|
||||
if (typeName.startsWith("minecraft:")) $REGISTRY.put(typeName.substring(10), existing);
|
||||
$REGISTRY.put(typeName, existing);
|
||||
return existing;
|
||||
}
|
||||
|
||||
public static final @Nullable EntityTypes get(final String id) {
|
||||
return $REGISTRY.get(id);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static final EntityTypes get(final int ordinal) {
|
||||
return values[ordinal];
|
||||
}
|
||||
|
||||
public static int size() {
|
||||
return values.length;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -19,29 +19,58 @@
|
||||
|
||||
package com.sk89q.worldedit.world.item;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.registry.NamespacedRegistry;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface ItemType {
|
||||
public class ItemType {
|
||||
|
||||
default ItemTypes toEnum() {
|
||||
return (ItemTypes) this;
|
||||
public static final NamespacedRegistry<ItemType> REGISTRY = new NamespacedRegistry<>("item type");
|
||||
|
||||
private String id;
|
||||
private BlockType blockType;
|
||||
private int internalId;
|
||||
private BaseItem defaultState;
|
||||
|
||||
public ItemType(String id) {
|
||||
// If it has no namespace, assume minecraft.
|
||||
if (!id.contains(":")) {
|
||||
id = "minecraft:" + id;
|
||||
}
|
||||
this.id = id;
|
||||
this.blockType = BlockTypes.get(this.id);
|
||||
}
|
||||
|
||||
String getId();
|
||||
|
||||
int getInternalId();
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public int getInternalId() {
|
||||
return this.internalId;
|
||||
}
|
||||
|
||||
public void setInternalId(int internalId) {
|
||||
this.internalId = internalId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this item, or the ID if the name cannot be found.
|
||||
*
|
||||
* @return The name, or ID
|
||||
*/
|
||||
String getName();
|
||||
public String getName() {
|
||||
String name = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getItemRegistry().getName(this);
|
||||
if (name == null) {
|
||||
return getId();
|
||||
} else {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -49,7 +78,7 @@ public interface ItemType {
|
||||
*
|
||||
* @return If it has a block
|
||||
*/
|
||||
default boolean hasBlockType() {
|
||||
public boolean hasBlockType() {
|
||||
return getBlockType() != null;
|
||||
}
|
||||
|
||||
@ -59,11 +88,34 @@ public interface ItemType {
|
||||
* @return The block representation
|
||||
*/
|
||||
@Nullable
|
||||
default BlockTypes getBlockType() {
|
||||
return BlockTypes.get(getId());
|
||||
public BlockType getBlockType() {
|
||||
return this.blockType;
|
||||
}
|
||||
|
||||
public void setBlockType(BlockType blockType) {
|
||||
this.blockType = blockType;
|
||||
}
|
||||
|
||||
public BaseItem getDefaultState() {
|
||||
return this.defaultState;
|
||||
}
|
||||
|
||||
public void setDefaultState(BaseItem defaultState) {
|
||||
this.defaultState = defaultState;
|
||||
}
|
||||
|
||||
default BaseItem getDefaultState() {
|
||||
return new BaseItem(this);
|
||||
@Override
|
||||
public String toString() {
|
||||
return getId();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.id.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof ItemType && this.id.equals(((ItemType) obj).id);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -55,7 +55,7 @@ public interface BlockRegistry {
|
||||
* @param blockType the block
|
||||
* @return a map of states where the key is the state's ID
|
||||
*/
|
||||
Map<String, ? extends Property> getProperties(BlockType blockType);
|
||||
Map<String, ? extends Property<?>> getProperties(BlockType blockType);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -41,7 +41,7 @@ public class BundledBlockRegistry implements BlockRegistry {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Map<String, ? extends Property> getProperties(BlockType blockType) {
|
||||
public Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
|
||||
return Collections.emptyMap(); // Oof
|
||||
}
|
||||
|
||||
|
@ -44,4 +44,11 @@ public class BundledItemRegistry implements ItemRegistry {
|
||||
public Collection<String> registerItems() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName(ItemType itemType) {
|
||||
BundledItemData.ItemEntry itemEntry = BundledItemData.getInstance().findById(itemType.getId());
|
||||
return itemEntry != null ? itemEntry.localizedName : null;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ package com.sk89q.worldedit.world.registry;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.world.entity.EntityType;
|
||||
import com.sk89q.worldedit.world.entity.EntityTypes;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
@ -43,7 +44,7 @@ public interface EntityRegistry {
|
||||
*/
|
||||
@Nullable
|
||||
default BaseEntity createFromId(String id) {
|
||||
EntityTypes entType = EntityTypes.get(id);
|
||||
EntityType entType = EntityTypes.get(id);
|
||||
return entType == null ? null : new BaseEntity(entType);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
package com.sk89q.worldedit.world.registry;
|
||||
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
@ -42,5 +43,14 @@ public interface ItemRegistry {
|
||||
default Collection<String> registerItems() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name for the given item.
|
||||
*
|
||||
* @param itemType the item
|
||||
* @return The name, or null if it's unknown
|
||||
*/
|
||||
@Nullable
|
||||
String getName(ItemType itemType);
|
||||
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ public class LegacyMapper {
|
||||
private final Int2ObjectArrayMap<Integer> blockStateToLegacyId4Data = new Int2ObjectArrayMap<>();
|
||||
private final Int2ObjectArrayMap<Integer> extraId4DataToStateId = new Int2ObjectArrayMap<>();
|
||||
private final int[] blockArr = new int[4096];
|
||||
private final BiMap<Integer, ItemTypes> itemMap = HashBiMap.create();
|
||||
private final BiMap<Integer, ItemType> itemMap = HashBiMap.create();
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
@ -96,7 +96,7 @@ public class LegacyMapper {
|
||||
try {
|
||||
BlockStateHolder blockState = BlockState.get(null, blockEntry.getValue());
|
||||
// BlockState blockState = WorldEdit.getInstance().getBlockFactory().parseFromInput(blockEntry.getValue(), parserContext).toImmutableState();
|
||||
BlockTypes type = blockState.getBlockType();
|
||||
BlockType type = blockState.getBlockType();
|
||||
if (type.hasProperty(PropertyKey.WATERLOGGED)) {
|
||||
blockState = blockState.with(PropertyKey.WATERLOGGED, false);
|
||||
}
|
||||
@ -134,11 +134,11 @@ public class LegacyMapper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ItemTypes getItemFromLegacy(int legacyId) {
|
||||
public ItemType getItemFromLegacy(int legacyId) {
|
||||
return itemMap.get(legacyId << 4);
|
||||
}
|
||||
|
||||
public ItemTypes getItemFromLegacy(String input) {
|
||||
public ItemType getItemFromLegacy(String input) {
|
||||
if (input.startsWith("minecraft:")) input = input.substring(10);
|
||||
return itemMap.get(getCombinedId(input));
|
||||
}
|
||||
@ -149,7 +149,7 @@ public class LegacyMapper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ItemTypes getItemFromLegacy(int legacyId, int data) {
|
||||
public ItemType getItemFromLegacy(int legacyId, int data) {
|
||||
return itemMap.get((legacyId << 4) + data);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user