Setup a legacy mapper system. The file does not exist yet.

This commit is contained in:
Matthew Miller 2018-07-01 22:03:22 +10:00
parent 8e09eb3dbe
commit b06937d1c8
31 changed files with 497 additions and 659 deletions

View File

@ -31,8 +31,6 @@ import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.LazyBlock;
import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.history.change.BlockChange;
@ -40,7 +38,7 @@ import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.AbstractWorld;
import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import org.bukkit.Effect;
import org.bukkit.TreeType;
import org.bukkit.World;
@ -361,10 +359,7 @@ public class BukkitWorld extends AbstractWorld {
@Override
public com.sk89q.worldedit.blocks.type.BlockState getBlock(Vector position) {
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
BlockType blockType = BlockTypes.getBlockType(
BundledBlockData.getInstance().fromLegacyId(bukkitBlock.getTypeId())
);
return blockType.getDefaultState(); // TODO Data
return LegacyMapper.getInstance().getBlockFromLegacy(bukkitBlock.getTypeId(), bukkitBlock.getData());
}
@Override
@ -374,7 +369,11 @@ public class BukkitWorld extends AbstractWorld {
return adapter.setBlock(BukkitAdapter.adapt(getWorld(), position), block, notifyAndLight);
} else {
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
return bukkitBlock.setTypeIdAndData(block.getBlockType().getLegacyId(), (byte) 0, notifyAndLight); // TODO Data
int[] datas = LegacyMapper.getInstance().getLegacyFromBlock(block.toImmutableState());
if (datas == null) {
throw new WorldEditException("Unknown block"){}; // TODO Remove.
}
return bukkitBlock.setTypeIdAndData(datas[0], (byte) datas[1], notifyAndLight);
}
}

View File

@ -19,13 +19,12 @@
package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import org.bukkit.BlockChangeDelegate;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.blocks.BaseBlock;
/**
* Proxy class to catch calls to set blocks.
@ -41,7 +40,7 @@ public class EditSessionBlockChangeDelegate implements BlockChangeDelegate {
@Override
public boolean setRawTypeId(int x, int y, int z, int typeId) {
try {
return editSession.setBlock(new Vector(x, y, z), new BaseBlock(typeId));
return editSession.setBlock(new Vector(x, y, z), LegacyMapper.getInstance().getBlockFromLegacy(typeId));
} catch (MaxChangedBlocksException ex) {
return false;
}
@ -50,7 +49,7 @@ public class EditSessionBlockChangeDelegate implements BlockChangeDelegate {
@Override
public boolean setRawTypeIdAndData(int x, int y, int z, int typeId, int data) {
try {
return editSession.setBlock(new Vector(x, y, z), new BaseBlock(typeId, data));
return editSession.setBlock(new Vector(x, y, z), LegacyMapper.getInstance().getBlockFromLegacy(typeId, data));
} catch (MaxChangedBlocksException ex) {
return false;
}
@ -68,7 +67,8 @@ public class EditSessionBlockChangeDelegate implements BlockChangeDelegate {
@Override
public int getTypeId(int x, int y, int z) {
return editSession.getBlock(new Vector(x, y, z)).getBlockType().getLegacyId();
int[] datas = LegacyMapper.getInstance().getLegacyFromBlock(editSession.getBlock(new Vector(x, y, z)));
return datas[0];
}
@Override

View File

@ -108,6 +108,7 @@ import com.sk89q.worldedit.util.eventbus.EventBus;
import com.sk89q.worldedit.world.NullWorld;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import java.util.ArrayList;
import java.util.Collections;
@ -440,10 +441,9 @@ public class EditSession implements Extent {
public int getHighestTerrainBlock(int x, int z, int minY, int maxY, boolean naturalOnly) {
for (int y = maxY; y >= minY; --y) {
Vector pt = new Vector(x, y, z);
BaseBlock block = getLazyBlock(pt);
int id = block.getId();
int data = block.getData();
if (naturalOnly ? BlockType.isNaturalTerrainBlock(id, data) : !BlockType.canPassThrough(id, data)) {
BlockState block = getBlock(pt);
int[] datas = LegacyMapper.getInstance().getLegacyFromBlock(block);
if (naturalOnly ? BlockType.isNaturalTerrainBlock(datas[0], datas[1]) : !BlockType.canPassThrough(datas[0], datas[1])) {
return y;
}
}
@ -2115,8 +2115,9 @@ public class EditSession implements Extent {
while (!queue.isEmpty()) {
final BlockVector current = queue.removeFirst();
final BaseBlock block = getLazyBlock(current);
if (!BlockType.canPassThrough(block.getId(), block.getData())) {
final BlockState block = getBlock(current);
int[] datas = LegacyMapper.getInstance().getLegacyFromBlock(block);
if (!BlockType.canPassThrough(datas[0], datas[1])) {
continue;
}

View File

@ -53,6 +53,7 @@ import com.sk89q.worldedit.util.io.file.InvalidFilenameException;
import com.sk89q.worldedit.util.logging.WorldEditPrefixHandler;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import com.sk89q.worldedit.world.registry.BundledItemData;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import java.io.DataInputStream;
import java.io.File;
@ -101,6 +102,7 @@ public class WorldEdit {
getVersion();
BundledBlockData.getInstance(); // Load block registry
BundledItemData.getInstance(); // Load item registry
LegacyMapper.getInstance(); // Load item registry
}
private WorldEdit() {

View File

@ -27,7 +27,7 @@ import com.sk89q.worldedit.blocks.type.BlockStateHolder;
import com.sk89q.worldedit.blocks.type.BlockType;
import com.sk89q.worldedit.blocks.type.BlockTypes;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import com.sk89q.worldedit.world.registry.state.State;
import com.sk89q.worldedit.world.registry.state.value.StateValue;
@ -52,9 +52,6 @@ import javax.annotation.Nullable;
*/
public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
// Instances of this class should be _as small as possible_ because there will
// be millions of instances of this object.
private BlockState blockState;
@Nullable
private CompoundTag nbtData;
@ -67,10 +64,12 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
@Deprecated
public BaseBlock(int id) {
try {
this.blockState = BlockTypes.getBlockType(BundledBlockData.getInstance().fromLegacyId(id)).getDefaultState();
this.blockState = LegacyMapper.getInstance().getBlockFromLegacy(id);
if (this.blockState == null) {
this.blockState = BlockTypes.AIR.getDefaultState();
}
} catch (Exception e) {
System.out.println(id);
System.out.println(BundledBlockData.getInstance().fromLegacyId(id));
e.printStackTrace();
}
}
@ -134,16 +133,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
* @param other the other block
*/
public BaseBlock(BaseBlock other) {
this(other.getState(), other.getNbtData());
}
/**
* Get the block state
*
* @return The block state
*/
public BlockState getState() {
return this.blockState;
this(other.toImmutableState(), other.getNbtData());
}
/**
@ -240,7 +230,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
final BaseBlock otherBlock = (BaseBlock) o;
return this.getState().equals(otherBlock.getState()) && Objects.equals(getNbtData(), otherBlock.getNbtData());
return this.toImmutableState().equals(otherBlock.toImmutableState()) && Objects.equals(getNbtData(), otherBlock.getNbtData());
}
@ -252,12 +242,17 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
*/
@Override
public boolean equalsFuzzy(BlockStateHolder o) {
return this.getState().equalsFuzzy(o);
return this.toImmutableState().equalsFuzzy(o);
}
@Override
public BlockState toImmutableState() {
return this.blockState;
}
@Override
public int hashCode() {
int ret = getState().hashCode() << 3;
int ret = toImmutableState().hashCode() << 3;
if (hasNbtData()) {
ret += getNbtData().hashCode();
}
@ -266,7 +261,7 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
@Override
public String toString() {
return "Block{State: " + this.getState().toString() + ", NBT: " + String.valueOf(getNbtData()) + "}";
return "Block{State: " + this.toImmutableState().toString() + ", NBT: " + String.valueOf(getNbtData()) + "}";
}
}

View File

@ -23,7 +23,7 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.blocks.type.ItemType;
import com.sk89q.worldedit.blocks.type.ItemTypes;
import com.sk89q.worldedit.world.NbtValued;
import com.sk89q.worldedit.world.registry.BundledItemData;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import javax.annotation.Nullable;
@ -46,7 +46,11 @@ public class BaseItem implements NbtValued {
*/
@Deprecated
public BaseItem(int id) {
this(ItemTypes.getItemType(BundledItemData.getInstance().fromLegacyId(id)));
ItemType type = LegacyMapper.getInstance().getItemFromLegacy(id);
if (type == null) {
type = ItemTypes.AIR;
}
this.itemType = type;
}
/**

View File

@ -855,246 +855,188 @@ public final class BlockData {
* @return the new data value for the block
*/
public static int cycle(int type, int data, int increment) {
if (increment != -1 && increment != 1) {
throw new IllegalArgumentException("Increment must be 1 or -1.");
}
int store;
switch (type) {
// special case here, going to use "forward" for type and "backward" for orientation
case BlockID.LOG:
case BlockID.LOG2:
if (increment == -1) {
store = data & 0x3; // copy bottom (type) bits
return mod((data & ~0x3) + 4, 16) | store; // switch orientation with top bits and reapply bottom bits;
} else {
store = data & ~0x3; // copy top (orientation) bits
return mod((data & 0x3) + 1, 4) | store; // switch type with bottom bits and reapply top bits
}
// <del>same here</del> - screw you unit tests
/*case BlockID.QUARTZ_BLOCK:
if (increment == -1 && data > 2) {
switch (data) {
case 2: return 3;
case 3: return 4;
case 4: return 2;
}
} else if (increment == 1) {
switch (data) {
case 0:
return 1;
case 1:
return 2;
case 2:
case 3:
case 4:
return 0;
}
} else {
return -1;
}*/
case BlockID.LONG_GRASS:
case BlockID.SANDSTONE:
case BlockID.DIRT:
if (data > 2) return -1;
return mod((data + increment), 3);
case BlockID.TORCH:
case BlockID.REDSTONE_TORCH_ON:
case BlockID.REDSTONE_TORCH_OFF:
if (data < 1 || data > 4) return -1;
return mod((data - 1 + increment), 4) + 1;
case BlockID.OAK_WOOD_STAIRS:
case BlockID.COBBLESTONE_STAIRS:
case BlockID.BRICK_STAIRS:
case BlockID.STONE_BRICK_STAIRS:
case BlockID.NETHER_BRICK_STAIRS:
case BlockID.SANDSTONE_STAIRS:
case BlockID.SPRUCE_WOOD_STAIRS:
case BlockID.BIRCH_WOOD_STAIRS:
case BlockID.JUNGLE_WOOD_STAIRS:
case BlockID.QUARTZ_STAIRS:
case BlockID.ACACIA_STAIRS:
case BlockID.DARK_OAK_STAIRS:
if (data > 7) return -1;
return mod((data + increment), 8);
case BlockID.STONE_BRICK:
case BlockID.QUARTZ_BLOCK:
case BlockID.PUMPKIN:
case BlockID.JACKOLANTERN:
case BlockID.NETHER_WART:
case BlockID.CAULDRON:
case BlockID.WOODEN_STEP:
case BlockID.DOUBLE_WOODEN_STEP:
case BlockID.HAY_BLOCK:
if (data > 3) return -1;
return mod((data + increment), 4);
case BlockID.STEP:
case BlockID.DOUBLE_STEP:
case BlockID.CAKE_BLOCK:
case BlockID.PISTON_BASE:
case BlockID.PISTON_STICKY_BASE:
case BlockID.SILVERFISH_BLOCK:
if (data > 5) return -1;
return mod((data + increment), 6);
case BlockID.DOUBLE_PLANT:
store = data & 0x8; // top half flag
data &= ~0x8;
if (data > 5) return -1;
return mod((data + increment), 6) | store;
case BlockID.CROPS:
case BlockID.PUMPKIN_STEM:
case BlockID.MELON_STEM:
if (data > 6) return -1;
return mod((data + increment), 7);
case BlockID.SOIL:
case BlockID.RED_FLOWER:
if (data > 8) return -1;
return mod((data + increment), 9);
case BlockID.RED_MUSHROOM_CAP:
case BlockID.BROWN_MUSHROOM_CAP:
if (data > 10) return -1;
return mod((data + increment), 11);
case BlockID.CACTUS:
case BlockID.REED:
case BlockID.SIGN_POST:
case BlockID.VINE:
case BlockID.SNOW:
case BlockID.COCOA_PLANT:
if (data > 15) return -1;
return mod((data + increment), 16);
case BlockID.FURNACE:
case BlockID.BURNING_FURNACE:
case BlockID.WALL_SIGN:
case BlockID.LADDER:
case BlockID.CHEST:
case BlockID.ENDER_CHEST:
case BlockID.TRAPPED_CHEST:
case BlockID.HOPPER:
int extra = data & 0x8;
int withoutFlags = data & ~0x8;
if (withoutFlags < 2 || withoutFlags > 5) return -1;
return (mod((withoutFlags - 2 + increment), 4) + 2) | extra;
case BlockID.DISPENSER:
case BlockID.DROPPER:
store = data & 0x8;
data &= ~0x8;
if (data > 5) return -1;
return mod((data + increment), 6) | store;
case BlockID.REDSTONE_REPEATER_OFF:
case BlockID.REDSTONE_REPEATER_ON:
case BlockID.COMPARATOR_OFF:
case BlockID.COMPARATOR_ON:
case BlockID.TRAP_DOOR:
case BlockID.FENCE_GATE:
case BlockID.LEAVES:
case BlockID.LEAVES2:
if (data > 7) return -1;
store = data & ~0x3;
return mod(((data & 0x3) + increment), 4) | store;
case BlockID.MINECART_TRACKS:
if (data < 6 || data > 9) return -1;
return mod((data - 6 + increment), 4) + 6;
case BlockID.SAPLING:
if ((data & 0x3) == 3 || data > 15) return -1;
store = data & ~0x3;
return mod(((data & 0x3) + increment), 3) | store;
case BlockID.FLOWER_POT:
if (data > 13) return -1;
return mod((data + increment), 14);
case BlockID.CLOTH:
case BlockID.STAINED_CLAY:
case BlockID.CARPET:
case BlockID.STAINED_GLASS:
case BlockID.STAINED_GLASS_PANE:
if (increment == 1) {
data = nextClothColor(data);
} else if (increment == -1) {
data = prevClothColor(data);
}
return data;
default:
return -1;
}
}
/**
* Returns the data value for the next color of cloth in the rainbow. This
* should not be used if you want to just increment the data value.
*
* @param data the data value
* @return the next data value
*/
public static int nextClothColor(int data) {
switch (data) {
case ClothColor.ID.WHITE: return ClothColor.ID.LIGHT_GRAY;
case ClothColor.ID.LIGHT_GRAY: return ClothColor.ID.GRAY;
case ClothColor.ID.GRAY: return ClothColor.ID.BLACK;
case ClothColor.ID.BLACK: return ClothColor.ID.BROWN;
case ClothColor.ID.BROWN: return ClothColor.ID.RED;
case ClothColor.ID.RED: return ClothColor.ID.ORANGE;
case ClothColor.ID.ORANGE: return ClothColor.ID.YELLOW;
case ClothColor.ID.YELLOW: return ClothColor.ID.LIGHT_GREEN;
case ClothColor.ID.LIGHT_GREEN: return ClothColor.ID.DARK_GREEN;
case ClothColor.ID.DARK_GREEN: return ClothColor.ID.CYAN;
case ClothColor.ID.CYAN: return ClothColor.ID.LIGHT_BLUE;
case ClothColor.ID.LIGHT_BLUE: return ClothColor.ID.BLUE;
case ClothColor.ID.BLUE: return ClothColor.ID.PURPLE;
case ClothColor.ID.PURPLE: return ClothColor.ID.MAGENTA;
case ClothColor.ID.MAGENTA: return ClothColor.ID.PINK;
case ClothColor.ID.PINK: return ClothColor.ID.WHITE;
}
return ClothColor.ID.WHITE;
}
/**
* Returns the data value for the previous ext color of cloth in the rainbow.
* This should not be used if you want to just increment the data value.
*
* @param data the data value
* @return the new data value
*/
public static int prevClothColor(int data) {
switch (data) {
case ClothColor.ID.LIGHT_GRAY: return ClothColor.ID.WHITE;
case ClothColor.ID.GRAY: return ClothColor.ID.LIGHT_GRAY;
case ClothColor.ID.BLACK: return ClothColor.ID.GRAY;
case ClothColor.ID.BROWN: return ClothColor.ID.BLACK;
case ClothColor.ID.RED: return ClothColor.ID.BROWN;
case ClothColor.ID.ORANGE: return ClothColor.ID.RED;
case ClothColor.ID.YELLOW: return ClothColor.ID.ORANGE;
case ClothColor.ID.LIGHT_GREEN: return ClothColor.ID.YELLOW;
case ClothColor.ID.DARK_GREEN: return ClothColor.ID.LIGHT_GREEN;
case ClothColor.ID.CYAN: return ClothColor.ID.DARK_GREEN;
case ClothColor.ID.LIGHT_BLUE: return ClothColor.ID.CYAN;
case ClothColor.ID.BLUE: return ClothColor.ID.LIGHT_BLUE;
case ClothColor.ID.PURPLE: return ClothColor.ID.BLUE;
case ClothColor.ID.MAGENTA: return ClothColor.ID.PURPLE;
case ClothColor.ID.PINK: return ClothColor.ID.MAGENTA;
case ClothColor.ID.WHITE: return ClothColor.ID.PINK;
}
return ClothColor.ID.WHITE;
return data + increment;
// TODO Fix
// if (increment != -1 && increment != 1) {
// throw new IllegalArgumentException("Increment must be 1 or -1.");
// }
//
// int store;
// switch (type) {
//
// // special case here, going to use "forward" for type and "backward" for orientation
// case BlockID.LOG:
// case BlockID.LOG2:
// if (increment == -1) {
// store = data & 0x3; // copy bottom (type) bits
// return mod((data & ~0x3) + 4, 16) | store; // switch orientation with top bits and reapply bottom bits;
// } else {
// store = data & ~0x3; // copy top (orientation) bits
// return mod((data & 0x3) + 1, 4) | store; // switch type with bottom bits and reapply top bits
// }
//
// // <del>same here</del> - screw you unit tests
// /*case BlockID.QUARTZ_BLOCK:
// if (increment == -1 && data > 2) {
// switch (data) {
// case 2: return 3;
// case 3: return 4;
// case 4: return 2;
// }
// } else if (increment == 1) {
// switch (data) {
// case 0:
// return 1;
// case 1:
// return 2;
// case 2:
// case 3:
// case 4:
// return 0;
// }
// } else {
// return -1;
// }*/
//
// case BlockID.LONG_GRASS:
// case BlockID.SANDSTONE:
// case BlockID.DIRT:
// if (data > 2) return -1;
// return mod((data + increment), 3);
//
// case BlockID.TORCH:
// case BlockID.REDSTONE_TORCH_ON:
// case BlockID.REDSTONE_TORCH_OFF:
// if (data < 1 || data > 4) return -1;
// return mod((data - 1 + increment), 4) + 1;
//
// case BlockID.OAK_WOOD_STAIRS:
// case BlockID.COBBLESTONE_STAIRS:
// case BlockID.BRICK_STAIRS:
// case BlockID.STONE_BRICK_STAIRS:
// case BlockID.NETHER_BRICK_STAIRS:
// case BlockID.SANDSTONE_STAIRS:
// case BlockID.SPRUCE_WOOD_STAIRS:
// case BlockID.BIRCH_WOOD_STAIRS:
// case BlockID.JUNGLE_WOOD_STAIRS:
// case BlockID.QUARTZ_STAIRS:
// case BlockID.ACACIA_STAIRS:
// case BlockID.DARK_OAK_STAIRS:
// if (data > 7) return -1;
// return mod((data + increment), 8);
//
// case BlockID.STONE_BRICK:
// case BlockID.QUARTZ_BLOCK:
// case BlockID.PUMPKIN:
// case BlockID.JACKOLANTERN:
// case BlockID.NETHER_WART:
// case BlockID.CAULDRON:
// case BlockID.WOODEN_STEP:
// case BlockID.DOUBLE_WOODEN_STEP:
// case BlockID.HAY_BLOCK:
// if (data > 3) return -1;
// return mod((data + increment), 4);
//
// case BlockID.STEP:
// case BlockID.DOUBLE_STEP:
// case BlockID.CAKE_BLOCK:
// case BlockID.PISTON_BASE:
// case BlockID.PISTON_STICKY_BASE:
// case BlockID.SILVERFISH_BLOCK:
// if (data > 5) return -1;
// return mod((data + increment), 6);
//
// case BlockID.DOUBLE_PLANT:
// store = data & 0x8; // top half flag
// data &= ~0x8;
// if (data > 5) return -1;
// return mod((data + increment), 6) | store;
//
// case BlockID.CROPS:
// case BlockID.PUMPKIN_STEM:
// case BlockID.MELON_STEM:
// if (data > 6) return -1;
// return mod((data + increment), 7);
//
// case BlockID.SOIL:
// case BlockID.RED_FLOWER:
// if (data > 8) return -1;
// return mod((data + increment), 9);
//
// case BlockID.RED_MUSHROOM_CAP:
// case BlockID.BROWN_MUSHROOM_CAP:
// if (data > 10) return -1;
// return mod((data + increment), 11);
//
// case BlockID.CACTUS:
// case BlockID.REED:
// case BlockID.SIGN_POST:
// case BlockID.VINE:
// case BlockID.SNOW:
// case BlockID.COCOA_PLANT:
// if (data > 15) return -1;
// return mod((data + increment), 16);
//
// case BlockID.FURNACE:
// case BlockID.BURNING_FURNACE:
// case BlockID.WALL_SIGN:
// case BlockID.LADDER:
// case BlockID.CHEST:
// case BlockID.ENDER_CHEST:
// case BlockID.TRAPPED_CHEST:
// case BlockID.HOPPER:
// int extra = data & 0x8;
// int withoutFlags = data & ~0x8;
// if (withoutFlags < 2 || withoutFlags > 5) return -1;
// return (mod((withoutFlags - 2 + increment), 4) + 2) | extra;
//
// case BlockID.DISPENSER:
// case BlockID.DROPPER:
// store = data & 0x8;
// data &= ~0x8;
// if (data > 5) return -1;
// return mod((data + increment), 6) | store;
//
// case BlockID.REDSTONE_REPEATER_OFF:
// case BlockID.REDSTONE_REPEATER_ON:
// case BlockID.COMPARATOR_OFF:
// case BlockID.COMPARATOR_ON:
// case BlockID.TRAP_DOOR:
// case BlockID.FENCE_GATE:
// case BlockID.LEAVES:
// case BlockID.LEAVES2:
// if (data > 7) return -1;
// store = data & ~0x3;
// return mod(((data & 0x3) + increment), 4) | store;
//
// case BlockID.MINECART_TRACKS:
// if (data < 6 || data > 9) return -1;
// return mod((data - 6 + increment), 4) + 6;
//
// case BlockID.SAPLING:
// if ((data & 0x3) == 3 || data > 15) return -1;
// store = data & ~0x3;
// return mod(((data & 0x3) + increment), 3) | store;
//
// case BlockID.FLOWER_POT:
// if (data > 13) return -1;
// return mod((data + increment), 14);
//
// case BlockID.CLOTH:
// case BlockID.STAINED_CLAY:
// case BlockID.CARPET:
// case BlockID.STAINED_GLASS:
// case BlockID.STAINED_GLASS_PANE:
// if (increment == 1) {
// data = nextClothColor(data);
// } else if (increment == -1) {
// data = prevClothColor(data);
// }
// return data;
//
// default:
// return -1;
// }
}
/**

View File

@ -1194,25 +1194,6 @@ public enum BlockType {
return isNaturalTerrainBlock.contains(-16*id-data) || isNaturalTerrainBlock.contains(id);
}
/**
* Checks if the block type is naturally occurring
*
* @param block the block
* @return true if the block type is naturally occurring
*/
public static boolean isNaturalTerrainBlock(BaseBlock block) {
return isNaturalTerrainBlock(block.getId(), block.getData());
}
/**
* Checks if the block type is naturally occurring
*
* @return true if the block type is naturally occurring
*/
public boolean isNaturalTerrainBlock() {
return isNaturalTerrainBlock.contains(id);
}
/**
* HashSet for emitsLight.
*/

View File

@ -31,61 +31,32 @@ import java.util.EnumSet;
*/
public enum ClothColor {
WHITE(ID.WHITE, "White", "white"),
ORANGE(ID.ORANGE, "Orange", "orange"),
MAGENTA(ID.MAGENTA, "Magenta", "magenta"),
LIGHT_BLUE(ID.LIGHT_BLUE, "Light blue", "lightblue"),
YELLOW(ID.YELLOW, "Yellow", "yellow"),
LIGHT_GREEN(ID.LIGHT_GREEN, "Light green", "lightgreen"),
PINK(ID.PINK, "Pink", new String[] { "pink", "lightred" }),
GRAY(ID.GRAY, "Gray", new String[] { "grey", "gray" }),
LIGHT_GRAY(ID.LIGHT_GRAY, "Light gray", new String[] { "lightgrey", "lightgray" }),
CYAN(ID.CYAN, "Cyan", new String[] { "cyan", "turquoise" }),
PURPLE(ID.PURPLE, "Purple", new String[] { "purple", "violet" }),
BLUE(ID.BLUE, "Blue", "blue"),
BROWN(ID.BROWN, "Brown", new String[] { "brown", "cocoa", "coffee" }),
DARK_GREEN(ID.DARK_GREEN, "Dark green", new String[] { "green", "darkgreen", "cactusgreen", "cactigreen" }),
RED(ID.RED, "Red", "red"),
BLACK(ID.BLACK, "Black", "black");
public static final class ID {
public static final int WHITE = 0;
public static final int ORANGE = 1;
public static final int MAGENTA = 2;
public static final int LIGHT_BLUE = 3;
public static final int YELLOW = 4;
public static final int LIGHT_GREEN = 5;
public static final int PINK = 6;
public static final int GRAY = 7;
public static final int LIGHT_GRAY = 8;
public static final int CYAN = 9;
public static final int PURPLE = 10;
public static final int BLUE = 11;
public static final int BROWN = 12;
public static final int DARK_GREEN = 13;
public static final int RED = 14;
public static final int BLACK = 15;
private ID() {
}
}
/**
* Stores a map of the IDs for fast access.
*/
private static final Map<Integer, ClothColor> ids = new HashMap<>();
WHITE("White", "white"),
ORANGE("Orange", "orange"),
MAGENTA("Magenta", "magenta"),
LIGHT_BLUE("Light blue", "lightblue"),
YELLOW("Yellow", "yellow"),
LIGHT_GREEN("Light green", "lightgreen"),
PINK("Pink", "pink", "lightred"),
GRAY("Gray", "grey", "gray"),
LIGHT_GRAY("Light gray", "lightgrey", "lightgray"),
CYAN("Cyan", "cyan", "turquoise"),
PURPLE("Purple", "purple", "violet"),
BLUE("Blue", "blue"),
BROWN("Brown", "brown", "cocoa", "coffee"),
DARK_GREEN("Dark green", "green", "darkgreen", "cactusgreen", "cactigreen"),
RED("Red", "red"),
BLACK("Black", "black");
/**
* Stores a map of the names for fast access.
*/
private static final Map<String, ClothColor> lookup = new HashMap<>();
private final int id;
private final String name;
private final String[] lookupKeys;
static {
for (ClothColor type : EnumSet.allOf(ClothColor.class)) {
ids.put(type.id, type);
for (String key : type.lookupKeys) {
lookup.put(key, type);
}
@ -96,40 +67,14 @@ public enum ClothColor {
/**
* Construct the type.
*
* @param id the ID of the color
* @param name the name of the color
* @param lookupKey a name to refer to the color by
* @param lookupKeys a name to refer to the color by
*/
ClothColor(int id, String name, String lookupKey) {
this.id = id;
this.name = name;
this.lookupKeys = new String[] { lookupKey };
}
/**
* Construct the type.
*
* @param id the ID of the color
* @param name the name of the color
* @param lookupKeys an array of lookup keys
*/
ClothColor(int id, String name, String[] lookupKeys) {
this.id = id;
ClothColor(String name, String ... lookupKeys) {
this.name = name;
this.lookupKeys = lookupKeys;
}
/**
* Return type from ID. May return null.
*
* @param id the ID
* @return a color or null
*/
@Nullable
public static ClothColor fromID(int id) {
return ids.get(id);
}
/**
* Return type from name. May return null.
*
@ -141,15 +86,6 @@ public enum ClothColor {
return lookup.get(name.toLowerCase());
}
/**
* Get item numeric ID.
*
* @return the ID
*/
public int getID() {
return id;
}
/**
* Get user-friendly item name.
*

View File

@ -141,6 +141,11 @@ public class BlockState implements BlockStateHolder<BlockState> {
return true;
}
@Override
public BlockState toImmutableState() {
return this;
}
/**
* Internal method used for creating the initial BlockState.
*

View File

@ -64,4 +64,11 @@ public interface BlockStateHolder<T extends BlockStateHolder> {
* @return true if equal
*/
boolean equalsFuzzy(BlockStateHolder o);
/**
* Returns an immutable BlockState from this BlockStateHolder.
*
* @return A BlockState
*/
BlockState toImmutableState();
}

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.blocks.type;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import java.util.function.Function;
@ -85,9 +86,9 @@ public class BlockType {
*/
@Deprecated
public int getLegacyId() {
Integer id = BundledBlockData.getInstance().toLegacyId(this.id);
int[] id = LegacyMapper.getInstance().getLegacyFromBlock(this.getDefaultState());
if (id != null) {
return id;
return id[0];
} else {
return 0;
}

View File

@ -19,8 +19,8 @@
package com.sk89q.worldedit.blocks.type;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import com.sk89q.worldedit.world.registry.BundledItemData;
import com.sk89q.worldedit.world.registry.LegacyMapper;
public class ItemType {
@ -61,9 +61,9 @@ public class ItemType {
*/
@Deprecated
public int getLegacyId() {
Integer id = BundledItemData.getInstance().toLegacyId(this.id);
if (id != null) {
return id;
int ids[] = LegacyMapper.getInstance().getLegacyFromItem(this);
if (ids != null) {
return ids[0];
} else {
return 0;
}

View File

@ -25,11 +25,13 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockData;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.registry.LegacyMapper;
/**
* A mode that cycles the data values of supported blocks.
@ -46,9 +48,10 @@ public class BlockDataCyler implements DoubleActionBlockTool {
World world = (World) clicked.getExtent();
BaseBlock block = world.getLazyBlock(clicked.toVector());
int type = block.getId();
int data = block.getData();
BlockState block = world.getBlock(clicked.toVector());
int[] datas = LegacyMapper.getInstance().getLegacyFromBlock(block);
int type = datas[0];
int data = datas[1];
if (!config.allowedDataCycleBlocks.isEmpty()
&& !player.hasPermission("worldedit.override.data-cycler")

View File

@ -153,6 +153,37 @@ class DefaultBlockParser extends InputParser<BlockStateHolder> {
}
}
private static BlockState applyProperties(BlockState state, String[] stateProperties) throws NoMatchException {
if (stateProperties.length > 0) { // Block data not yet detected
// Parse the block data (optional)
for (String parseableData : stateProperties) {
try {
String[] parts = parseableData.split("=");
if (parts.length != 2) {
throw new NoMatchException("Bad state format in " + parseableData);
}
State stateKey = BundledBlockData.getInstance().findById(state.getBlockType().getId()).states.get(parts[0]);
if (stateKey == null) {
throw new NoMatchException("Unknown state " + parts[0] + " for block " + state.getBlockType().getName());
}
StateValue value = stateKey.getValueFor(parts[1]);
if (value == null) {
throw new NoMatchException("Unknown value " + parts[1] + " for state " + parts[0]);
}
state = state.with(stateKey, value);
} catch (NoMatchException e) {
throw e; // Pass-through
} catch (Exception e) {
throw new NoMatchException("Unknown state '" + parseableData + "'");
}
}
}
return state;
}
private BlockStateHolder parseLogic(String input, ParserContext context) throws InputParseException {
BlockType blockType;
Map<State, StateValue> blockStates = new HashMap<>();
@ -217,39 +248,16 @@ class DefaultBlockParser extends InputParser<BlockStateHolder> {
state = new BlockState(blockType, blockStates);
}
if (stateProperties.length > 0) { // Block data not yet detected
// Parse the block data (optional)
for (String parseableData : stateProperties) {
try {
String[] parts = parseableData.split("=");
if (parts.length != 2) {
throw new NoMatchException("Bad state format in " + parseableData);
}
State stateKey = BundledBlockData.getInstance().findById(blockType.getId()).states.get(parts[0]);
if (stateKey == null) {
throw new NoMatchException("Unknown state " + parts[0] + " for block " + blockType.getName());
}
StateValue value = stateKey.getValueFor(parts[1]);
if (value == null) {
throw new NoMatchException("Unknown value " + parts[1] + " for state " + parts[0]);
}
state = state.with(stateKey, value);
} catch (NoMatchException e) {
throw e; // Pass-through
} catch (Exception e) {
throw new NoMatchException("Unknown state '" + parseableData + "'");
}
}
}
state = applyProperties(state, stateProperties);
// Check if the item is allowed
if (context.isRestricted()) {
Actor actor = context.requireActor();
if (context.isRestricted() && actor != null && !actor.hasPermission("worldedit.anyblock")
if (actor != null && !actor.hasPermission("worldedit.anyblock")
&& worldEdit.getConfiguration().disallowedBlocks.contains(blockType.getId())) {
throw new DisallowedUsageException("You are not allowed to use '" + input + "'");
}
}
if (blockType == BlockTypes.SIGN || blockType == BlockTypes.WALL_SIGN) {
// Allow special sign text syntax

View File

@ -128,11 +128,7 @@ public class BlockArrayClipboard implements Clipboard {
Vector v = position.subtract(region.getMinimumPoint());
BlockStateHolder block = blocks[v.getBlockX()][v.getBlockY()][v.getBlockZ()];
if (block != null) {
if (block instanceof BlockState) {
return (BlockState) block;
} else if (block instanceof BaseBlock) {
return ((BaseBlock) block).getState();
}
return block.toImmutableState();
}
}

View File

@ -105,7 +105,7 @@ public class ExtentBlockCopy implements RegionFunction {
builder.putByte("Rot", (byte) MCDirections.toRotation(newDirection));
return new BaseBlock(state.getState(), builder.build());
return new BaseBlock(state.toImmutableState(), builder.build());
}
}
}

View File

@ -24,7 +24,7 @@ package com.sk89q.worldedit.util;
import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.world.registry.BundledItemData;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
import java.io.File;
@ -92,7 +92,7 @@ public class PropertiesConfiguration extends LocalConfiguration {
registerHelp = getBool("register-help", registerHelp);
wandItem = getString("wand-item", wandItem);
try {
wandItem = BundledItemData.getInstance().fromLegacyId(Integer.parseInt(wandItem));
wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId();
} catch (Throwable e) {
}
superPickaxeDrop = getBool("super-pickaxe-drop-items", superPickaxeDrop);
@ -103,7 +103,7 @@ public class PropertiesConfiguration extends LocalConfiguration {
useInventoryCreativeOverride = getBool("use-inventory-creative-override", useInventoryCreativeOverride);
navigationWand = getString("nav-wand-item", navigationWand);
try {
navigationWand = BundledItemData.getInstance().fromLegacyId(Integer.parseInt(navigationWand));
navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId();
} catch (Throwable e) {
}
navigationWandMaxDistance = getInt("nav-wand-distance", navigationWandMaxDistance);

View File

@ -25,6 +25,7 @@ import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.session.SessionManager;
import com.sk89q.worldedit.world.registry.BundledItemData;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
import java.io.IOException;
@ -57,7 +58,7 @@ public class YAMLConfiguration extends LocalConfiguration {
profile = config.getBoolean("debug", profile);
wandItem = config.getString("wand-item", wandItem);
try {
wandItem = BundledItemData.getInstance().fromLegacyId(Integer.parseInt(wandItem));
wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId();
} catch (Throwable e) {
}
@ -105,7 +106,7 @@ public class YAMLConfiguration extends LocalConfiguration {
navigationWand = config.getString("navigation-wand.item", navigationWand);
try {
navigationWand = BundledItemData.getInstance().fromLegacyId(Integer.parseInt(navigationWand));
navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId();
} catch (Throwable e) {
}
navigationWandMaxDistance = config.getInt("navigation-wand.max-distance", navigationWandMaxDistance);

View File

@ -42,16 +42,6 @@ public interface BlockRegistry {
@Nullable
BlockState createFromId(String id);
/**
* Create a new block using its legacy numeric ID.
*
* @param id the id
* @return the block, which may be null if no block exists
*/
@Nullable
@Deprecated
BlockState createFromId(int id);
/**
* Get the material for the given block.
*

View File

@ -56,7 +56,6 @@ public class BundledBlockData {
private static final BundledBlockData INSTANCE = new BundledBlockData();
private final Map<String, BlockEntry> idMap = new HashMap<>();
private final Map<Integer, BlockEntry> legacyMap = new HashMap<>(); // Trove usage removed temporarily
/**
* Create a new instance.
@ -87,7 +86,7 @@ public class BundledBlockData {
for (BlockEntry entry : entries) {
idMap.put(entry.id, entry);
legacyMap.put(entry.legacyId, entry);
entry.postDeserialization();
}
}
@ -106,49 +105,6 @@ public class BundledBlockData {
return idMap.get(id);
}
/**
* Return the entry for the given block legacy numeric ID.
*
* @param id the ID
* @return the entry, or null
*/
@Nullable
private BlockEntry findById(int id) {
return legacyMap.get(id);
}
/**
* Convert the given string ID to a legacy numeric ID.
*
* @param id the ID
* @return the legacy ID, which may be null if the block does not have a legacy ID
*/
@Nullable
public Integer toLegacyId(String id) {
BlockEntry entry = findById(id);
if (entry != null) {
return entry.legacyId;
} else {
return null;
}
}
/**
* Convert the given legacy numeric ID to a string ID.
*
* @param id the legacy ID
* @return the ID, which may be null if the block does not have a ID
*/
@Nullable
public String fromLegacyId(Integer id) {
BlockEntry entry = findById(id);
if (entry != null) {
return entry.id;
} else {
return null;
}
}
/**
* Get the material properties for the given block.
*
@ -191,13 +147,18 @@ public class BundledBlockData {
}
public static class BlockEntry {
private int legacyId;
private String id;
private String unlocalizedName;
public String localizedName;
private List<String> aliases;
public Map<String, SimpleState> states = new HashMap<>();
private SimpleBlockMaterial material = new SimpleBlockMaterial();
void postDeserialization() {
for (Map.Entry<String, SimpleState> state : states.entrySet()) {
state.getValue().setName(state.getKey());
}
}
}
}

View File

@ -41,17 +41,6 @@ public class BundledBlockRegistry implements BlockRegistry {
return BlockTypes.getBlockType(id).getDefaultState();
}
@Nullable
@Override
public BlockState createFromId(int legacyId) {
String id = BundledBlockData.getInstance().fromLegacyId(legacyId);
if (id != null) {
return createFromId(id);
} else {
return null;
}
}
@Nullable
@Override
public BlockMaterial getMaterial(BaseBlock block) {

View File

@ -54,7 +54,6 @@ public class BundledItemData {
private static final BundledItemData INSTANCE = new BundledItemData();
private final Map<String, ItemEntry> idMap = new HashMap<>();
private final Map<Integer, ItemEntry> legacyMap = new HashMap<>(); // Trove usage removed temporarily
/**
* Create a new instance.
@ -85,9 +84,6 @@ public class BundledItemData {
for (ItemEntry entry : entries) {
idMap.put(entry.id, entry);
if (entry.legacyId >= 0) {
legacyMap.put(entry.legacyId, entry);
}
}
}
@ -97,7 +93,8 @@ public class BundledItemData {
* @param id the ID
* @return the entry, or null
*/
@Nullable public ItemEntry findById(String id) {
@Nullable
public ItemEntry findById(String id) {
// If it has no namespace, assume minecraft.
if (!id.contains(":")) {
id = "minecraft:" + id;
@ -105,49 +102,6 @@ public class BundledItemData {
return idMap.get(id);
}
/**
* Return the entry for the given item legacy numeric ID.
*
* @param id the ID
* @return the entry, or null
*/
@Nullable
private ItemEntry findById(int id) {
return legacyMap.get(id);
}
/**
* Convert the given string ID to a legacy numeric ID.
*
* @param id the ID
* @return the legacy ID, which may be null if the item does not have a legacy ID
*/
@Nullable
public Integer toLegacyId(String id) {
ItemEntry entry = findById(id);
if (entry != null) {
return entry.legacyId;
} else {
return null;
}
}
/**
* Convert the given legacy numeric ID to a string ID.
*
* @param id the legacy ID
* @return the ID, which may be null if the item does not have a ID
*/
@Nullable
public String fromLegacyId(Integer id) {
ItemEntry entry = findById(id);
if (entry != null) {
return entry.id;
} else {
return null;
}
}
/**
* Get a singleton instance of this object.
*
@ -158,8 +112,6 @@ public class BundledItemData {
}
public static class ItemEntry {
private int legacyId; // -1 for items without legacy IDs.
private short legacyData;
private String id;
private String unlocalizedName;
public String localizedName;

View File

@ -35,15 +35,4 @@ public class BundledItemRegistry implements ItemRegistry {
public BaseItem createFromId(String id) {
return new BaseItem(ItemTypes.getItemType(id));
}
@Nullable
@Override
public BaseItem createFromId(int legacyId) {
String id = BundledItemData.getInstance().fromLegacyId(legacyId);
if (id != null) {
return createFromId(id);
} else {
return null;
}
}
}

View File

@ -34,13 +34,4 @@ public interface ItemRegistry {
@Nullable
BaseItem createFromId(String id);
/**
* Create a new item using its legacy numeric ID.
*
* @param id the id
* @return the item, which may be null if no item exists
*/
@Nullable
BaseItem createFromId(int id);
}

View File

@ -0,0 +1,152 @@
/*
* 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.registry;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.io.Resources;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.type.BlockState;
import com.sk89q.worldedit.blocks.type.ItemType;
import com.sk89q.worldedit.blocks.type.ItemTypes;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.util.gson.VectorAdapter;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
public class LegacyMapper {
private static final Logger log = Logger.getLogger(LegacyMapper.class.getCanonicalName());
private static final LegacyMapper INSTANCE = new LegacyMapper();
private BiMap<String, BlockState> blockMap = HashBiMap.create();
private BiMap<String, ItemType> itemMap = HashBiMap.create();
/**
* Create a new instance.
*/
private LegacyMapper() {
try {
loadFromResource();
} catch (IOException e) {
log.log(Level.WARNING, "Failed to load the built-in legacy id registry", e);
}
}
/**
* Attempt to load the data from file.
*
* @throws IOException thrown on I/O error
*/
private void loadFromResource() throws IOException {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Vector.class, new VectorAdapter());
Gson gson = gsonBuilder.disableHtmlEscaping().create();
URL url = LegacyMapper.class.getResource("legacy.json");
if (url == null) {
throw new IOException("Could not find legacy.json");
}
String data = Resources.toString(url, Charset.defaultCharset());
LegacyDataFile dataFile = gson.fromJson(data, new TypeToken<LegacyDataFile>() {}.getType());
ParserContext parserContext = new ParserContext();
parserContext.setPreferringWildcard(false);
parserContext.setRestricted(false);
for (Map.Entry<String, String> blockEntry : dataFile.blocks.entrySet()) {
try {
blockMap.put(blockEntry.getKey(),
(BlockState) WorldEdit.getInstance().getBlockFactory().parseFromInput(blockEntry.getValue(), parserContext));
} catch (Exception e) {
log.warning("Unknown block: " + blockEntry.getValue());
}
}
for (Map.Entry<String, String> itemEntry : dataFile.items.entrySet()) {
try {
itemMap.put(itemEntry.getKey(), ItemTypes.getItemType(itemEntry.getValue()));
} catch (Exception e) {
log.warning("Unknown item: " + itemEntry.getValue());
}
}
}
@Nullable
public ItemType getItemFromLegacy(int legacyId) {
return itemMap.get(legacyId + ":0");
}
@Nullable
public ItemType getItemFromLegacy(int legacyId, int data) {
return itemMap.get(legacyId + ":" + data);
}
@Nullable
public int[] getLegacyFromItem(ItemType itemType) {
if (!itemMap.inverse().containsKey(itemType)) {
return null;
} else {
String value = itemMap.inverse().get(itemType);
return Arrays.stream(value.split(":")).mapToInt(Integer::parseInt).toArray();
}
}
@Nullable
public BlockState getBlockFromLegacy(int legacyId) {
return blockMap.get(legacyId + ":0");
}
@Nullable
public BlockState getBlockFromLegacy(int legacyId, int data) {
return blockMap.get(legacyId + ":" + data);
}
@Nullable
public int[] getLegacyFromBlock(BlockState blockState) {
if (!blockMap.inverse().containsKey(blockState)) {
return null;
} else {
String value = blockMap.inverse().get(blockState);
return Arrays.stream(value.split(":")).mapToInt(Integer::parseInt).toArray();
}
}
public static LegacyMapper getInstance() {
return INSTANCE;
}
@SuppressWarnings({"MismatchedQueryAndUpdateOfCollection", "unused"})
private static class LegacyDataFile {
private Map<String, String> blocks;
private Map<String, String> items;
}
}

View File

@ -29,6 +29,7 @@ import javax.annotation.Nullable;
public class SimpleState<T extends SimpleStateValue> implements State<T> {
private String name;
private List<T> values;
/**
@ -37,9 +38,21 @@ public class SimpleState<T extends SimpleStateValue> implements State<T> {
* @param values The values
*/
public SimpleState(List<T> values) {
this.name = "Unknown";
this.values = values;
}
/**
* Internal method for name setting post-deserialise. Do not use.
*/
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
@Override
public List<T> getValues() {
return Collections.unmodifiableList(values);

View File

@ -33,6 +33,13 @@ import javax.annotation.Nullable;
*/
public interface State<T extends SimpleStateValue> {
/**
* Returns the name of this state.
*
* @return The state name
*/
String getName();
/**
* Return a list of available values for this state.
*

View File

@ -61,80 +61,4 @@ public class BlockDataTest {
}
}
}
private static final TreeSet<Integer> datasTemplate = new TreeSet<Integer>();
static {
for (int data = 0; data < 16; ++data) {
datasTemplate.add(data);
}
}
@Test
public void testCycle() {
// Test monotony and continuity
for (int type = 0; type < 256; ++type) {
// Cloth isn't monotonous, and thus excluded.
if (type == BlockID.CLOTH
|| type == BlockID.STAINED_CLAY
|| type == BlockID.STAINED_GLASS
|| type == BlockID.STAINED_GLASS_PANE
|| type == BlockID.CARPET) {
continue;
}
for (int data = 0; data < 16; ++data) {
final String message = type + "/" + data;
final int cycled = BlockData.cycle(type, data, 1);
// If the cycle goes back (including -1), everything is ok.
if (cycled <= data) {
continue;
}
// If there's a gap in the cycle, there's a problem.
assertEquals(message, data + 1, cycled);
}
}
// Test cyclicity forwards
testCycle(1);
// ...and backwards
testCycle(-1);
}
private static void testCycle(final int increment) {
// Iterate each block type and data value that wasn't part of a cycle yet.
for (int type = 0; type < 256; ++type) {
@SuppressWarnings("unchecked")
final TreeSet<Integer> datas = (TreeSet<Integer>) datasTemplate.clone();
while (!datas.isEmpty()) {
final int start = datas.pollFirst();
String message = type + "/" + start;
int current = start;
boolean first = true;
while (true) {
current = BlockData.cycle(type, current, increment);
// If the cycle immediately goes to -1, everything is ok.
if (first && current == -1) break;
first = false;
message += "->" + current;
// If the cycle goes off limits (including -1), there's a problem.
assertTrue(message, current >= 0);
assertTrue(message, current < 16);
// The cycle completes, everything is ok.
if (current == start) break;
// Mark the current element as walked.
assertTrue(message, datas.remove(current));
}
}
}
}
}

View File

@ -37,14 +37,4 @@ public class ForgeItemRegistry implements ItemRegistry {
return null;
}
}
@Nullable
@Override
public BaseItem createFromId(int id) {
if (Item.REGISTRY.getObjectById(id) != null) {
return new BaseItem(id);
} else {
return null;
}
}
}

View File

@ -22,9 +22,8 @@ package com.sk89q.worldedit.sponge.config;
import com.google.common.reflect.TypeToken;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.blocks.type.ItemTypes;
import com.sk89q.worldedit.session.SessionManager;
import com.sk89q.worldedit.world.registry.BundledItemData;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import com.sk89q.worldedit.world.snapshot.SnapshotRepository;
import ninja.leaping.configurate.ConfigurationOptions;
import ninja.leaping.configurate.commented.CommentedConfigurationNode;
@ -61,7 +60,7 @@ public class ConfigurateConfiguration extends LocalConfiguration {
profile = node.getNode("debug").getBoolean(profile);
wandItem = node.getNode("wand-item").getString(wandItem);
try {
wandItem = BundledItemData.getInstance().fromLegacyId(Integer.parseInt(wandItem));
wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId();
} catch (Throwable e) {
}
@ -105,7 +104,7 @@ public class ConfigurateConfiguration extends LocalConfiguration {
navigationWand = node.getNode("navigation-wand", "item").getString(navigationWand);
try {
navigationWand = BundledItemData.getInstance().fromLegacyId(Integer.parseInt(navigationWand));
navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId();
} catch (Throwable e) {
}
navigationWandMaxDistance = node.getNode("navigation-wand", "max-distance").getInt(navigationWandMaxDistance);