some hasty refactoring

This commit is contained in:
Jesse Boyd
2018-08-28 02:56:28 +10:00
parent a61c856adc
commit abd886acd7
55 changed files with 1238 additions and 819 deletions

View File

@ -19,15 +19,16 @@
package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.bekvon.bukkit.residence.commands.material;
import com.sk89q.worldedit.NotABlockException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.IBukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.SimpleBukkitAdapter;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockState;
@ -39,347 +40,136 @@ import com.sk89q.worldedit.world.entity.EntityTypes;
import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Adapts between Bukkit and WorldEdit equivalent objects.
*/
public class BukkitAdapter {
public enum BukkitAdapter {
INSTANCE
;
private final IBukkitAdapter adapter;
private static final ParserContext TO_BLOCK_CONTEXT = new ParserContext();
static {
TO_BLOCK_CONTEXT.setRestricted(false);
BukkitAdapter() {
BukkitImplAdapter tmp = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (tmp != null) {
this.adapter = tmp;
} else {
this.adapter = new SimpleBukkitAdapter();
}
}
private static final IBukkitAdapter getAdapter() {
return INSTANCE.adapter;
}
/**
* Checks equality between a WorldEdit BlockType and a Bukkit Material
*
* @param blockType The WorldEdit BlockType
* @param type The Bukkit Material
* @return If they are equal
*/
public static boolean equals(BlockType blockType, Material type) {
return Objects.equals(blockType.getId(), type.getKey().toString());
return getAdapter().equals(blockType, type);
}
/**
* Convert any WorldEdit world into an equivalent wrapped Bukkit world.
*
* <p>If a matching world cannot be found, a {@link RuntimeException}
* will be thrown.</p>
*
* @param world the world
* @return a wrapped Bukkit world
*/
public static BukkitWorld asBukkitWorld(World world) {
if (world instanceof BukkitWorld) {
return (BukkitWorld) world;
} else {
BukkitWorld bukkitWorld = WorldEditPlugin.getInstance().getInternalPlatform().matchWorld(world);
if (bukkitWorld == null) {
throw new RuntimeException("World '" + world.getName() + "' has no matching version in Bukkit");
}
return bukkitWorld;
}
return getAdapter().asBukkitWorld(world);
}
/**
* Create a WorldEdit world from a Bukkit world.
*
* @param world the Bukkit world
* @return a WorldEdit world
*/
public static World adapt(org.bukkit.World world) {
checkNotNull(world);
return new BukkitWorld(world);
return getAdapter().adapt(world);
}
/**
* Create a Bukkit world from a WorldEdit world.
*
* @param world the WorldEdit world
* @return a Bukkit world
*/
public static org.bukkit.World adapt(World world) {
checkNotNull(world);
if (world instanceof BukkitWorld) {
return ((BukkitWorld) world).getWorld();
} else {
org.bukkit.World match = Bukkit.getServer().getWorld(world.getName());
if (match != null) {
return match;
} else {
throw new IllegalArgumentException("Can't find a Bukkit world for " + world);
}
}
return getAdapter().adapt(world);
}
/**
* Create a WorldEdit location from a Bukkit location.
*
* @param location the Bukkit location
* @return a WorldEdit location
*/
public static Location adapt(org.bukkit.Location location) {
checkNotNull(location);
Vector position = asVector(location);
return new com.sk89q.worldedit.util.Location(
adapt(location.getWorld()),
position,
location.getYaw(),
location.getPitch());
return getAdapter().adapt(location);
}
/**
* Create a Bukkit location from a WorldEdit location.
*
* @param location the WorldEdit location
* @return a Bukkit location
*/
public static org.bukkit.Location adapt(Location location) {
checkNotNull(location);
Vector position = location.toVector();
return new org.bukkit.Location(
adapt((World) location.getExtent()),
position.getX(), position.getY(), position.getZ(),
location.getYaw(),
location.getPitch());
return getAdapter().adapt(location);
}
/**
* Create a Bukkit location from a WorldEdit position with a Bukkit world.
*
* @param world the Bukkit world
* @param position the WorldEdit position
* @return a Bukkit location
*/
public static org.bukkit.Location adapt(org.bukkit.World world, Vector position) {
checkNotNull(world);
checkNotNull(position);
return new org.bukkit.Location(
world,
position.getX(), position.getY(), position.getZ());
return getAdapter().adapt(world, position);
}
/**
* Create a Bukkit location from a WorldEdit location with a Bukkit world.
*
* @param world the Bukkit world
* @param location the WorldEdit location
* @return a Bukkit location
*/
public static org.bukkit.Location adapt(org.bukkit.World world, Location location) {
checkNotNull(world);
checkNotNull(location);
return new org.bukkit.Location(
world,
location.getX(), location.getY(), location.getZ(),
location.getYaw(),
location.getPitch());
return getAdapter().adapt(world, location);
}
/**
* Create a WorldEdit Vector from a Bukkit location.
*
* @param location The Bukkit location
* @return a WorldEdit vector
*/
public static Vector asVector(org.bukkit.Location location) {
checkNotNull(location);
return new Vector(location.getX(), location.getY(), location.getZ());
return getAdapter().asVector(location);
}
/**
* Create a WorldEdit entity from a Bukkit entity.
*
* @param entity the Bukkit entity
* @return a WorldEdit entity
*/
public static Entity adapt(org.bukkit.entity.Entity entity) {
checkNotNull(entity);
return new BukkitEntity(entity);
return getAdapter().adapt(entity);
}
/**
* Create a Bukkit Material form a WorldEdit ItemType
*
* @param itemType The WorldEdit ItemType
* @return The Bukkit Material
*/
public static Material adapt(ItemType itemType) {
checkNotNull(itemType);
if (!itemType.getId().startsWith("minecraft:")) {
throw new IllegalArgumentException("Bukkit only supports Minecraft items");
}
return Material.getMaterial(itemType.getId().substring(10).toUpperCase());
return getAdapter().adapt(itemType);
}
/**
* Create a Bukkit Material form a WorldEdit BlockType
*
* @param blockType The WorldEdit BlockType
* @return The Bukkit Material
*/
public static Material adapt(BlockType blockType) {
checkNotNull(blockType);
if (!blockType.getId().startsWith("minecraft:")) {
throw new IllegalArgumentException("Bukkit only supports Minecraft blocks");
}
String id = blockType.getId().substring(10).toUpperCase();
return Material.getMaterial(id);
return getAdapter().adapt(blockType);
}
/**
* Create a WorldEdit GameMode from a Bukkit one.
*
* @param gameMode Bukkit GameMode
* @return WorldEdit GameMode
*/
public static GameMode adapt(org.bukkit.GameMode gameMode) {
checkNotNull(gameMode);
return GameModes.get(gameMode.name().toLowerCase());
return getAdapter().adapt(gameMode);
}
/**
* Create a WorldEdit EntityType from a Bukkit one.
*
* @param entityType Bukkit EntityType
* @return WorldEdit EntityType
*/
public static EntityType adapt(org.bukkit.entity.EntityType entityType) {
return EntityTypes.get(entityType.getName().toLowerCase());
return getAdapter().adapt(entityType);
}
public static org.bukkit.entity.EntityType adapt(EntityType entityType) {
if (!entityType.getId().startsWith("minecraft:")) {
throw new IllegalArgumentException("Bukkit only supports vanilla entities");
}
return org.bukkit.entity.EntityType.fromName(entityType.getId().substring(10).toLowerCase());
return getAdapter().adapt(entityType);
}
/**
* Converts a Material to a BlockType
*
* @param material The material
* @return The blocktype
*/
public static BlockType asBlockType(Material material) {
checkNotNull(material);
if (!material.isBlock()) {
throw new IllegalArgumentException(material.getKey().toString() + " is not a block!") {
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
};
}
return BlockTypes.get(material.getKey().toString());
return getAdapter().asBlockType(material);
}
/**
* Converts a Material to a ItemType
*
* @param material The material
* @return The itemtype
*/
public static ItemType asItemType(Material material) {
return CachedBukkitAdapter.asItemType(material);
return getAdapter().asItemType(material);
}
/**
* Create a WorldEdit BlockStateHolder from a Bukkit BlockData
*
* @param blockData The Bukkit BlockData
* @return The WorldEdit BlockState
*/
public static BlockState adapt(BlockData blockData) {
return CachedBukkitAdapter.adapt(blockData);
}
public static BlockData getBlockData(int combinedId) {
return CachedBukkitAdapter.getBlockData(combinedId);
return getAdapter().adapt(blockData);
}
public static BlockTypes adapt(Material material) {
return CachedBukkitAdapter.adapt(material);
return getAdapter().adapt(material);
}
/**
* Create a Bukkit BlockData from a WorldEdit BlockStateHolder
*
* @param block The WorldEdit BlockStateHolder
* @return The Bukkit BlockData
*/
public static BlockData adapt(BlockStateHolder block) {
return CachedBukkitAdapter.adapt(block);
return getAdapter().adapt(block);
}
public static BlockData getBlockData(int combinedId) {
return getAdapter().getBlockData(combinedId);
}
/**
* Create a WorldEdit BlockStateHolder from a Bukkit ItemStack
*
* @param itemStack The Bukkit ItemStack
* @return The WorldEdit BlockState
*/
public static BlockState asBlockState(ItemStack itemStack) {
checkNotNull(itemStack);
if (itemStack.getType().isBlock()) {
return adapt(itemStack.getType().createBlockData());
} else {
throw new NotABlockException();
}
return getAdapter().asBlockState(itemStack);
}
/**
* Create a WorldEdit BaseItemStack from a Bukkit ItemStack
*
* @param itemStack The Bukkit ItemStack
* @return The WorldEdit BaseItemStack
*/
public static BaseItemStack adapt(ItemStack itemStack) {
checkNotNull(itemStack);
return new BukkitItemStack(itemStack);
return getAdapter().adapt(itemStack);
}
/**
* Create a Bukkit ItemStack from a WorldEdit BaseItemStack
*
* @param item The WorldEdit BaseItemStack
* @return The Bukkit ItemStack
*/
public static ItemStack adapt(BaseItemStack item) {
checkNotNull(item);
if (item instanceof BukkitItemStack) return ((BukkitItemStack) item).getBukkitItemStack();
return new ItemStack(adapt(item.getType()), item.getAmount());
return getAdapter().adapt(item);
}
/**
* Create a WorldEdit Player from a Bukkit Player.
*
* @param player The Bukkit player
* @return The WorldEdit player
*/
public static BukkitPlayer adapt(Player player) {
return WorldEditPlugin.getInstance().wrapPlayer(player);
return getAdapter().adapt(player);
}
/**
* Create a Bukkit Player from a WorldEdit Player.
*
* @param player The WorldEdit player
* @return The Bukkit player
*/
public static Player adapt(com.sk89q.worldedit.entity.Player player) {
return ((BukkitPlayer) player).getPlayer();
return getAdapter().adapt(player);
}
}

View File

@ -21,8 +21,10 @@ package com.sk89q.worldedit.bukkit;
import com.bekvon.bukkit.residence.commands.material;
import com.sk89q.worldedit.blocks.BlockMaterial;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.command.tool.BlockDataCyler;
import com.sk89q.worldedit.registry.state.Property;
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;
@ -42,24 +44,49 @@ import javax.annotation.Nullable;
public class BukkitBlockRegistry extends BundledBlockRegistry {
private Map<Material, BukkitBlockMaterial> materialMap = new EnumMap<>(Material.class);
private BukkitBlockMaterial[] materialMap;
@Nullable
@Override
public BlockMaterial getMaterial(BlockType blockType) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
BlockMaterial result = adapter.getMaterial(blockType);
if (result != null) return result;
}
Material type = BukkitAdapter.adapt(blockType);
if (type == null) {
if (blockType == BlockTypes.__RESERVED__) return new PassthroughBlockMaterial(super.getMaterial(BlockTypes.AIR));
return new PassthroughBlockMaterial(null);
}
return materialMap.computeIfAbsent(type, m -> new BukkitBlockMaterial(BukkitBlockRegistry.super.getMaterial(blockType), m));
if (materialMap == null) {
materialMap = new BukkitBlockMaterial[Material.values().length];
}
BukkitBlockMaterial result = materialMap[type.ordinal()];
if (result == null) {
result = new BukkitBlockMaterial(BukkitBlockRegistry.super.getMaterial(blockType), type);
materialMap[type.ordinal()] = result;
}
return result;
}
@Nullable
@Override
public BlockMaterial getMaterial(BlockState state) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
BlockMaterial result = adapter.getMaterial(state);
if (result != null) return result;
}
return super.getMaterial(state);
}
@Nullable
@Override
public Map<String, ? extends Property> getProperties(BlockType blockType) {
if (WorldEditPlugin.getInstance().getBukkitImplAdapter() != null) {
return WorldEditPlugin.getInstance().getBukkitImplAdapter().getProperties(blockType);
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
return adapter.getProperties(blockType);
}
return super.getProperties(blockType);
}

View File

@ -36,7 +36,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
/**
* An adapter to adapt a Bukkit entity into a WorldEdit one.
*/
class BukkitEntity implements Entity {
public class BukkitEntity implements Entity {
private final WeakReference<org.bukkit.entity.Entity> entityRef;
@ -45,7 +45,7 @@ class BukkitEntity implements Entity {
*
* @param entity the entity
*/
BukkitEntity(org.bukkit.entity.Entity entity) {
public BukkitEntity(org.bukkit.entity.Entity entity) {
checkNotNull(entity);
this.entityRef = new WeakReference<>(entity);
}

View File

@ -445,7 +445,10 @@ public class BukkitWorld extends AbstractWorld {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
try {
return adapter.setBlock(BukkitAdapter.adapt(getWorld(), position), block, notifyAndLight);
int x = position.getBlockX();
int y = position.getBlockY();
int z = position.getBlockZ();
return adapter.setBlock(getWorld().getChunkAt(x >> 4, z >> 4), x, y, z, block, true);
} catch (Exception e) {
if (block.getNbtData() != null) {
logger.warning("Tried to set a corrupt tile entity at " + position.toString());

View File

@ -1,110 +0,0 @@
package com.sk89q.worldedit.bukkit;
import com.bekvon.bukkit.residence.commands.material;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.block.data.BlockData;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
public class CachedBukkitAdapter {
private static final BlockData[][] blockDataCache = new BlockData[BlockTypes.size()][];
private static final ItemTypes[] itemTypes;
private static final BlockTypes[] blockTypes;
static {
Material[] materials = Material.values();
itemTypes = new ItemTypes[materials.length];
blockTypes = new BlockTypes[materials.length];
for (int i = 0; i < materials.length; i++) {
Material material = materials[i];
if (material.isLegacy()) continue;
NamespacedKey key = material.getKey();
String id = key.getNamespace() + ":" + key.getKey();
if (material.isBlock()) {
blockTypes[i] = BlockTypes.get(id);
}
if (material.isItem()) {
itemTypes[i] = ItemTypes.get(id);
}
}
blockDataCache[0] = new BlockData[] {Material.AIR.createBlockData()};
}
/**
* Converts a Material to a ItemType
*
* @param material The material
* @return The itemtype
*/
public static ItemType asItemType(Material material) {
return itemTypes[material.ordinal()];
}
/**
* Create a WorldEdit BlockStateHolder from a Bukkit BlockData
*
* @param blockData The Bukkit BlockData
* @return The WorldEdit BlockState
*/
public static BlockState adapt(BlockData blockData) {
checkNotNull(blockData);
Material material = blockData.getMaterial();
BlockTypes type = blockTypes[material.ordinal()];
List<? extends Property> propList = type.getProperties();
if (propList.size() == 0) return type.getDefaultState();
String properties = blockData.getAsString();
return BlockState.get(type, properties, type.getDefaultState().getInternalPropertiesId());
}
public static BlockData getBlockData(int combinedId) {
int typeId = combinedId & BlockTypes.BIT_MASK;
BlockData[] dataCache = blockDataCache[typeId];
if (dataCache == null) {
BlockTypes type = BlockTypes.get(typeId);
blockDataCache[typeId] = dataCache = new BlockData[type.getMaxStateId() + 1];
}
int propId = combinedId >> BlockTypes.BIT_OFFSET;
BlockData blockData = dataCache[propId];
if (blockData == null) {
dataCache[propId] = blockData = Bukkit.createBlockData(BlockState.get(combinedId).getAsString());
}
return blockData;
}
public static BlockTypes adapt(Material material) {
return blockTypes[material.ordinal()];
}
/**
* Create a Bukkit BlockData from a WorldEdit BlockStateHolder
*
* @param block The WorldEdit BlockStateHolder
* @return The Bukkit BlockData
*/
public static BlockData adapt(BlockStateHolder block) {
checkNotNull(block);
int typeId = block.getInternalBlockTypeId();
BlockData[] dataCache = blockDataCache[typeId];
if (dataCache == null) {
BlockTypes type = BlockTypes.get(typeId);
blockDataCache[typeId] = dataCache = new BlockData[type.getMaxStateId() + 1];
}
int propId = block.getInternalPropertiesId();
BlockData blockData = dataCache[propId];
if (blockData == null) {
dataCache[propId] = blockData = Bukkit.createBlockData(block.getAsString());
}
return blockData;
}
}

View File

@ -21,7 +21,7 @@ package com.sk89q.worldedit.bukkit;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.bukkit.adapter.Spigot_v1_13_R1;
import com.boydti.fawe.bukkit.adapter.v1_13_1.Spigot_v1_13_R2;
import com.boydti.fawe.util.MainUtil;
import com.google.common.base.Joiner;
import com.sk89q.util.yaml.YAMLProcessor;
@ -33,7 +33,6 @@ import com.sk89q.worldedit.bukkit.adapter.AdapterLoadException;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplLoader;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
@ -45,7 +44,6 @@ import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.bukkit.plugin.*;
import org.bukkit.plugin.java.JavaPlugin;
@ -277,7 +275,11 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
// Attempt to load a Bukkit adapter
BukkitImplLoader adapterLoader = new BukkitImplLoader();
adapterLoader.addClass(Spigot_v1_13_R1.class);
try {
adapterLoader.addClass(Spigot_v1_13_R2.class);
} catch (Throwable ignore) {
ignore.printStackTrace();
}
try {
adapterLoader.addFromPath(getClass().getClassLoader());
@ -491,7 +493,7 @@ public class WorldEditPlugin extends JavaPlugin //implements TabCompleter
return new BukkitCommandSender(this, sender);
}
BukkitServerInterface getInternalPlatform() {
public BukkitServerInterface getInternalPlatform() {
return server;
}

View File

@ -21,13 +21,14 @@ package com.sk89q.worldedit.bukkit.adapter;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockMaterial;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.world.block.BlockType;
import net.minecraft.server.v1_13_R1.NBTBase;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.block.Biome;
import org.bukkit.entity.Entity;
@ -39,7 +40,7 @@ import javax.annotation.Nullable;
/**
* An interface for adapters of various Bukkit implementations.
*/
public interface BukkitImplAdapter<T> {
public interface BukkitImplAdapter<T> extends IBukkitAdapter {
/**
* Get the biome ID for the given biome.
@ -69,15 +70,9 @@ public interface BukkitImplAdapter<T> {
*/
BlockState getBlock(Location location);
/**
* Set the block at the given location.
*
* @param location the location
* @param state the block
* @param notifyAndLight notify and light if set
* @return true if a block was likely changed
*/
boolean setBlock(Location location, BlockStateHolder state, boolean notifyAndLight);
boolean setBlock(Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update);
boolean isChunkInUse(Chunk chunk);
/**
* Get the state for the given entity.
@ -106,6 +101,14 @@ public interface BukkitImplAdapter<T> {
*/
Map<String, ? extends Property> getProperties(BlockType blockType);
default BlockMaterial getMaterial(BlockType blockType) {
return null;
}
default BlockMaterial getMaterial(BlockState blockState) {
return null;
}
default Tag toNative(T foreign) {
return null;
}

View File

@ -170,6 +170,7 @@ public class BukkitImplLoader {
log.log(Level.WARNING, "Failed to load the Bukkit adapter class '" + className +
"' that is not supposed to be raising this error", e);
} catch (Throwable e) {
e.printStackTrace();
if (className.equals(customCandidate)) {
log.log(Level.WARNING, "Failed to load the Bukkit adapter class '" + className + "'", e);
}

View File

@ -0,0 +1,93 @@
package com.sk89q.worldedit.bukkit.adapter;
import com.bekvon.bukkit.residence.commands.material;
import com.sk89q.worldedit.bukkit.adapter.IBukkitAdapter;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.block.data.BlockData;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
public abstract class CachedBukkitAdapter implements IBukkitAdapter {
private int[] itemTypes;
private int[] blockTypes;
private boolean init() {
if (itemTypes == null) {
Material[] materials = Material.values();
itemTypes = new int[materials.length];
blockTypes = new int[materials.length];
for (int i = 0; i < materials.length; i++) {
Material material = materials[i];
if (material.isLegacy()) continue;
NamespacedKey key = material.getKey();
String id = key.getNamespace() + ":" + key.getKey();
if (material.isBlock()) {
blockTypes[i] = BlockTypes.get(id).getInternalId();
}
if (material.isItem()) {
itemTypes[i] = ItemTypes.get(id).getInternalId();
}
}
return true;
}
return false;
}
/**
* Converts a Material to a ItemType
*
* @param material The material
* @return The itemtype
*/
@Override
public ItemType asItemType(Material material) {
try {
return ItemTypes.values[itemTypes[material.ordinal()]];
} catch (NullPointerException e) {
if (init()) return asItemType(material);
return ItemTypes.values[itemTypes[material.ordinal()]];
}
}
@Override
public BlockTypes adapt(Material material) {
try {
return BlockTypes.values[blockTypes[material.ordinal()]];
} catch (NullPointerException e) {
if (init()) return adapt(material);
throw e;
}
}
/**
* Create a WorldEdit BlockStateHolder from a Bukkit BlockData
*
* @param blockData The Bukkit BlockData
* @return The WorldEdit BlockState
*/
@Override
public BlockState adapt(BlockData blockData) {
try {
checkNotNull(blockData);
Material material = blockData.getMaterial();
BlockTypes type = BlockTypes.getFromStateId(blockTypes[material.ordinal()]);
List<? extends Property> propList = type.getProperties();
if (propList.size() == 0) return type.getDefaultState();
String properties = blockData.getAsString();
return BlockState.get(type, properties, type.getDefaultState());
} catch (NullPointerException e) {
if (init()) return adapt(blockData);
throw e;
}
}
}

View File

@ -0,0 +1,341 @@
package com.sk89q.worldedit.bukkit.adapter;
import com.sk89q.worldedit.NotABlockException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.*;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.util.Location;
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.entity.EntityType;
import com.sk89q.worldedit.world.entity.EntityTypes;
import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldedit.world.item.ItemType;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import static com.google.common.base.Preconditions.checkNotNull;
public interface IBukkitAdapter {
/**
* Checks equality between a WorldEdit BlockType and a Bukkit Material
*
* @param blockType The WorldEdit BlockType
* @param type The Bukkit Material
* @return If they are equal
*/
default boolean equals(BlockType blockType, Material type) {
return blockType == asItemType(type).getBlockType();
}
/**
* Convert any WorldEdit world into an equivalent wrapped Bukkit world.
*
* <p>If a matching world cannot be found, a {@link RuntimeException}
* will be thrown.</p>
*
* @param world the world
* @return a wrapped Bukkit world
*/
default BukkitWorld asBukkitWorld(World world) {
if (world instanceof BukkitWorld) {
return (BukkitWorld) world;
} else {
BukkitWorld bukkitWorld = WorldEditPlugin.getInstance().getInternalPlatform().matchWorld(world);
if (bukkitWorld == null) {
throw new RuntimeException("World '" + world.getName() + "' has no matching version in Bukkit");
}
return bukkitWorld;
}
}
/**
* Create a WorldEdit world from a Bukkit world.
*
* @param world the Bukkit world
* @return a WorldEdit world
*/
default World adapt(org.bukkit.World world) {
checkNotNull(world);
return new BukkitWorld(world);
}
/**
* Create a Bukkit world from a WorldEdit world.
*
* @param world the WorldEdit world
* @return a Bukkit world
*/
default org.bukkit.World adapt(World world) {
checkNotNull(world);
if (world instanceof BukkitWorld) {
return ((BukkitWorld) world).getWorld();
} else {
org.bukkit.World match = Bukkit.getServer().getWorld(world.getName());
if (match != null) {
return match;
} else {
throw new IllegalArgumentException("Can't find a Bukkit world for " + world);
}
}
}
/**
* Create a WorldEdit location from a Bukkit location.
*
* @param location the Bukkit location
* @return a WorldEdit location
*/
default Location adapt(org.bukkit.Location location) {
checkNotNull(location);
Vector position = asVector(location);
return new com.sk89q.worldedit.util.Location(
adapt(location.getWorld()),
position,
location.getYaw(),
location.getPitch());
}
/**
* Create a Bukkit location from a WorldEdit location.
*
* @param location the WorldEdit location
* @return a Bukkit location
*/
default org.bukkit.Location adapt(Location location) {
checkNotNull(location);
Vector position = location.toVector();
return new org.bukkit.Location(
adapt((World) location.getExtent()),
position.getX(), position.getY(), position.getZ(),
location.getYaw(),
location.getPitch());
}
/**
* Create a Bukkit location from a WorldEdit position with a Bukkit world.
*
* @param world the Bukkit world
* @param position the WorldEdit position
* @return a Bukkit location
*/
default org.bukkit.Location adapt(org.bukkit.World world, Vector position) {
checkNotNull(world);
checkNotNull(position);
return new org.bukkit.Location(
world,
position.getX(), position.getY(), position.getZ());
}
/**
* Create a Bukkit location from a WorldEdit location with a Bukkit world.
*
* @param world the Bukkit world
* @param location the WorldEdit location
* @return a Bukkit location
*/
default org.bukkit.Location adapt(org.bukkit.World world, Location location) {
checkNotNull(world);
checkNotNull(location);
return new org.bukkit.Location(
world,
location.getX(), location.getY(), location.getZ(),
location.getYaw(),
location.getPitch());
}
/**
* Create a WorldEdit Vector from a Bukkit location.
*
* @param location The Bukkit location
* @return a WorldEdit vector
*/
default Vector asVector(org.bukkit.Location location) {
checkNotNull(location);
return new Vector(location.getX(), location.getY(), location.getZ());
}
/**
* Create a WorldEdit entity from a Bukkit entity.
*
* @param entity the Bukkit entity
* @return a WorldEdit entity
*/
default Entity adapt(org.bukkit.entity.Entity entity) {
checkNotNull(entity);
return new BukkitEntity(entity);
}
/**
* Create a Bukkit Material form a WorldEdit ItemType
*
* @param itemType The WorldEdit ItemType
* @return The Bukkit Material
*/
default Material adapt(ItemType itemType) {
checkNotNull(itemType);
if (!itemType.getId().startsWith("minecraft:")) {
throw new IllegalArgumentException("Bukkit only supports Minecraft items");
}
return Material.getMaterial(itemType.getId().substring(10).toUpperCase());
}
/**
* Create a Bukkit Material form a WorldEdit BlockType
*
* @param blockType The WorldEdit BlockType
* @return The Bukkit Material
*/
default Material adapt(BlockType blockType) {
checkNotNull(blockType);
if (!blockType.getId().startsWith("minecraft:")) {
throw new IllegalArgumentException("Bukkit only supports Minecraft blocks");
}
String id = blockType.getId().substring(10).toUpperCase();
return Material.getMaterial(id);
}
/**
* Create a WorldEdit GameMode from a Bukkit one.
*
* @param gameMode Bukkit GameMode
* @return WorldEdit GameMode
*/
default GameMode adapt(org.bukkit.GameMode gameMode) {
checkNotNull(gameMode);
return GameModes.get(gameMode.name().toLowerCase());
}
/**
* Create a WorldEdit EntityType from a Bukkit one.
*
* @param entityType Bukkit EntityType
* @return WorldEdit EntityType
*/
default EntityType adapt(org.bukkit.entity.EntityType entityType) {
return EntityTypes.get(entityType.getName().toLowerCase());
}
default org.bukkit.entity.EntityType adapt(EntityType entityType) {
if (!entityType.getId().startsWith("minecraft:")) {
throw new IllegalArgumentException("Bukkit only supports vanilla entities");
}
return org.bukkit.entity.EntityType.fromName(entityType.getId().substring(10).toLowerCase());
}
/**
* Converts a Material to a BlockType
*
* @param material The material
* @return The blocktype
*/
default BlockType asBlockType(Material material) {
checkNotNull(material);
if (!material.isBlock()) {
throw new IllegalArgumentException(material.getKey().toString() + " is not a block!") {
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
};
}
return BlockTypes.get(material.getKey().toString());
}
/**
* Converts a Material to a ItemType
*
* @param material The material
* @return The itemtype
*/
ItemType asItemType(Material material);
/**
* Create a WorldEdit BlockStateHolder from a Bukkit BlockData
*
* @param blockData The Bukkit BlockData
* @return The WorldEdit BlockState
*/
BlockState adapt(BlockData blockData);
BlockTypes adapt(Material material);
/**
* Create a Bukkit BlockData from a WorldEdit BlockStateHolder
*
* @param block The WorldEdit BlockStateHolder
* @return The Bukkit BlockData
*/
BlockData adapt(BlockStateHolder block);
default BlockData getBlockData(int combinedId) {
return adapt(BlockState.getFromInternalId(combinedId));
}
/**
* Create a WorldEdit BlockStateHolder from a Bukkit ItemStack
*
* @param itemStack The Bukkit ItemStack
* @return The WorldEdit BlockState
*/
default BlockState asBlockState(ItemStack itemStack) {
checkNotNull(itemStack);
if (itemStack.getType().isBlock()) {
return adapt(itemStack.getType().createBlockData());
} else {
throw new NotABlockException();
}
}
/**
* Create a WorldEdit BaseItemStack from a Bukkit ItemStack
*
* @param itemStack The Bukkit ItemStack
* @return The WorldEdit BaseItemStack
*/
default BaseItemStack adapt(ItemStack itemStack) {
checkNotNull(itemStack);
return new BukkitItemStack(itemStack);
}
/**
* Create a Bukkit ItemStack from a WorldEdit BaseItemStack
*
* @param item The WorldEdit BaseItemStack
* @return The Bukkit ItemStack
*/
default ItemStack adapt(BaseItemStack item) {
checkNotNull(item);
if (item instanceof BukkitItemStack) return ((BukkitItemStack) item).getBukkitItemStack();
return new ItemStack(adapt(item.getType()), item.getAmount());
}
/**
* Create a WorldEdit Player from a Bukkit Player.
*
* @param player The Bukkit player
* @return The WorldEdit player
*/
default BukkitPlayer adapt(Player player) {
return WorldEditPlugin.getInstance().wrapPlayer(player);
}
/**
* Create a Bukkit Player from a WorldEdit Player.
*
* @param player The WorldEdit player
* @return The Bukkit player
*/
default Player adapt(com.sk89q.worldedit.entity.Player player) {
return ((BukkitPlayer) player).getPlayer();
}
}

View File

@ -0,0 +1,48 @@
package com.sk89q.worldedit.bukkit.adapter;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import static com.google.common.base.Preconditions.checkNotNull;
public class SimpleBukkitAdapter extends CachedBukkitAdapter {
private BlockData[][] blockDataCache;
public boolean init() {
if (blockDataCache != null) return false;
this.blockDataCache = new BlockData[BlockTypes.size()][];
blockDataCache[0] = new BlockData[] {Material.AIR.createBlockData()};
return true;
}
/**
* Create a Bukkit BlockData from a WorldEdit BlockStateHolder
*
* @param block The WorldEdit BlockStateHolder
* @return The Bukkit BlockData
*/
@Override
public BlockData adapt(BlockStateHolder block) {
try {
checkNotNull(block);
int typeId = block.getInternalBlockTypeId();
BlockData[] dataCache = blockDataCache[typeId];
if (dataCache == null) {
BlockTypes type = BlockTypes.get(typeId);
blockDataCache[typeId] = dataCache = new BlockData[type.getMaxStateId() + 1];
}
int propId = block.getInternalPropertiesId();
BlockData blockData = dataCache[propId];
if (blockData == null) {
dataCache[propId] = blockData = Bukkit.createBlockData(block.getAsString());
}
return blockData;
} catch (NullPointerException e) {
if (init()) return adapt(block);
throw e;
}
}
}