Copy paste/merge FAWE classes to this WorldEdit fork

- so certain people can look at the diff and complain about my sloppy code :(

Signed-off-by: Jesse Boyd <jessepaleg@gmail.com>
This commit is contained in:
Jesse Boyd
2018-08-13 00:03:07 +10:00
parent a920c77cb8
commit a629d15c74
994 changed files with 117583 additions and 10745 deletions

View File

@ -35,7 +35,11 @@ import java.util.Set;
public class CommandRegistration {
static {
Bukkit.getServer().getHelpMap().registerHelpTopicFactory(DynamicPluginCommand.class, new DynamicPluginCommandHelpTopic.Factory());
try {
Bukkit.getServer().getHelpMap().registerHelpTopicFactory(DynamicPluginCommand.class, new DynamicPluginCommandHelpTopic.Factory());
} catch (Throwable e) {
e.printStackTrace();
}
}
protected final Plugin plugin;

View File

@ -34,9 +34,8 @@ public class FallbackRegistrationListener implements Listener {
@EventHandler(ignoreCancelled = true)
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
if (commandRegistration.dispatch(event.getPlayer(), event.getMessage())) {
if (commandRegistration.dispatch(event.getPlayer(), event.getMessage().substring(1))) {
event.setCancelled(true);
}
}
}
}

View File

@ -19,16 +19,16 @@
package com.sk89q.wepif;
import com.sk89q.util.yaml.YAMLNode;
import com.sk89q.util.yaml.YAMLProcessor;
import org.bukkit.OfflinePlayer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.sk89q.util.yaml.YAMLNode;
import com.sk89q.util.yaml.YAMLProcessor;
import org.bukkit.OfflinePlayer;
public class ConfigurationPermissionsResolver implements PermissionsResolver {
private YAMLProcessor config;
private Map<String, Set<String>> userPermissionsCache;

View File

@ -19,7 +19,6 @@
package com.sk89q.wepif;
import com.nijikokun.bukkit.Permissions.Permissions;
import com.sk89q.util.yaml.YAMLProcessor;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
@ -28,6 +27,7 @@ import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import com.nijikokun.bukkit.Permissions.Permissions;
import java.util.logging.Level;
import java.util.logging.Logger;

View File

@ -21,6 +21,7 @@ package com.sk89q.wepif;
import com.sk89q.util.yaml.YAMLFormat;
import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.event.EventHandler;
@ -102,7 +103,6 @@ public class PermissionsResolverManager implements PermissionsResolver {
protected PermissionsResolverManager(Plugin plugin) {
this.server = plugin.getServer();
(new ServerListener()).register(plugin); // Register the events
loadConfig(new File("wepif.yml"));
findResolver();
}

View File

@ -21,13 +21,12 @@ package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Function;
import com.bekvon.bukkit.residence.commands.material;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extension.input.InputParseException;
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;
@ -40,24 +39,19 @@ 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.HashMap;
import java.util.Map;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nullable;
/**
* Adapts between Bukkit and WorldEdit equivalent objects.
*/
public class BukkitAdapter {
private BukkitAdapter() {
}
private static final ParserContext TO_BLOCK_CONTEXT = new ParserContext();
static {
@ -107,26 +101,6 @@ public class BukkitAdapter {
return new BukkitWorld(world);
}
/**
* 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);
}
/**
* 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();
}
/**
* Create a Bukkit world from a WorldEdit world.
*
@ -247,6 +221,8 @@ public class BukkitAdapter {
return Material.getMaterial(itemType.getId().replace("minecraft:", "").toUpperCase());
}
private static boolean test;
/**
* Create a Bukkit Material form a WorldEdit BlockType
*
@ -258,7 +234,8 @@ public class BukkitAdapter {
if (!blockType.getId().startsWith("minecraft:")) {
throw new IllegalArgumentException("Bukkit only supports Minecraft blocks");
}
return Material.getMaterial(blockType.getId().replace("minecraft:", "").toUpperCase());
String id = blockType.getId().substring(10).toUpperCase();
return Material.getMaterial(id);
}
/**
@ -281,11 +258,18 @@ public class BukkitAdapter {
public static BlockType asBlockType(Material material) {
checkNotNull(material);
if (!material.isBlock()) {
throw new IllegalArgumentException(material.getKey().toString() + " is not a block!");
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
*
@ -293,35 +277,25 @@ public class BukkitAdapter {
* @return The itemtype
*/
public static ItemType asItemType(Material material) {
checkNotNull(material);
if (!material.isItem()) {
throw new IllegalArgumentException(material.getKey().toString() + " is not an item!");
}
return ItemTypes.get(material.getKey().toString());
return CachedBukkitAdapter.asItemType(material);
}
private static Map<String, BlockState> blockStateCache = new HashMap<>();
/**
* Create a WorldEdit BlockState from a Bukkit BlockData
* 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);
return blockStateCache.computeIfAbsent(blockData.getAsString(), new Function<String, BlockState>() {
@Nullable
@Override
public BlockState apply(@Nullable String input) {
try {
return WorldEdit.getInstance().getBlockFactory().parseFromInput(input, TO_BLOCK_CONTEXT).toImmutableState();
} catch (InputParseException e) {
e.printStackTrace();
return null;
}
}
});
return CachedBukkitAdapter.adapt(blockData);
}
public static BlockData getBlockData(int combinedId) {
return CachedBukkitAdapter.getBlockData(combinedId);
}
public static BlockTypes adapt(Material material) {
return CachedBukkitAdapter.adapt(material);
}
/**
@ -331,17 +305,16 @@ public class BukkitAdapter {
* @return The Bukkit BlockData
*/
public static BlockData adapt(BlockStateHolder block) {
checkNotNull(block);
return Bukkit.createBlockData(block.getAsString());
return CachedBukkitAdapter.adapt(block);
}
/**
* Create a WorldEdit BlockState from a Bukkit ItemStack
* Create a WorldEdit BlockStateHolder from a Bukkit ItemStack
*
* @param itemStack The Bukkit ItemStack
* @return The WorldEdit BlockState
*/
public static BlockState asBlockState(ItemStack itemStack) {
public static BlockStateHolder asBlockState(ItemStack itemStack) {
checkNotNull(itemStack);
if (itemStack.getType().isBlock()) {
return adapt(itemStack.getType().createBlockData());
@ -358,6 +331,8 @@ public class BukkitAdapter {
*/
public static BaseItemStack adapt(ItemStack itemStack) {
checkNotNull(itemStack);
return new BaseItemStack(ItemTypes.get(itemStack.getType().getKey().toString()), itemStack.getAmount());
}
@ -371,4 +346,23 @@ public class BukkitAdapter {
checkNotNull(item);
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
*/
public static 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
*/
public static Player adapt(com.sk89q.worldedit.entity.Player player) {
return ((BukkitPlayer) player).getPlayer();
}
}

View File

@ -25,12 +25,11 @@ import com.sk89q.worldedit.world.biome.BiomeData;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import org.bukkit.block.Biome;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
/**
* A biome registry for Bukkit.
*/

View File

@ -19,13 +19,21 @@
package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import com.bekvon.bukkit.residence.commands.material;
import com.sk89q.worldedit.blocks.BlockMaterial;
import com.sk89q.worldedit.command.tool.BlockDataCyler;
import com.sk89q.worldedit.registry.state.Property;
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.BundledBlockRegistry;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import com.sk89q.worldedit.world.registry.PassthroughBlockMaterial;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.Map;
@ -38,7 +46,11 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
@Nullable
@Override
public BlockMaterial getMaterial(BlockType blockType) {
return materialMap.computeIfAbsent(BukkitAdapter.adapt(blockType),
Material type = BukkitAdapter.adapt(blockType);
if (type == null) {
type = Material.AIR;
}
return materialMap.computeIfAbsent(type,
material -> new BukkitBlockMaterial(BukkitBlockRegistry.super.getMaterial(blockType), material));
}
@ -75,4 +87,16 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
return material.isTransparent();
}
}
@Override
public Collection<String> registerBlocks() {
ArrayList<String> blocks = new ArrayList<>();
for (Material m : Material.values()) {
if (!m.isLegacy() && m.isBlock()) {
BlockData blockData = m.createBlockData();
blocks.add(blockData.getAsString());
}
}
return blocks;
}
}

View File

@ -19,8 +19,6 @@
package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.bukkit.util.CommandInspector;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.worldedit.extension.platform.Actor;
@ -32,6 +30,8 @@ import org.bukkit.command.CommandSender;
import java.util.logging.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
class BukkitCommandInspector implements CommandInspector {
private static final Logger logger = Logger.getLogger(BukkitCommandInspector.class.getCanonicalName());

View File

@ -19,22 +19,24 @@
package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.entity.metadata.Metadatable;
import com.sk89q.worldedit.session.SessionKey;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.io.File;
import java.util.UUID;
import javax.annotation.Nullable;
import java.io.File;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class BukkitCommandSender implements Actor {
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
public class BukkitCommandSender implements Actor, Metadatable {
/**
* One time generated ID.
@ -43,6 +45,7 @@ public class BukkitCommandSender implements Actor {
private CommandSender sender;
private WorldEditPlugin plugin;
private ConcurrentHashMap<String, Object> meta;
public BukkitCommandSender(WorldEditPlugin plugin, CommandSender sender) {
checkNotNull(plugin);
@ -53,6 +56,12 @@ public class BukkitCommandSender implements Actor {
this.sender = sender;
}
@Override
public synchronized Map<String, Object> getMetaMap() {
if (meta == null) meta = new ConcurrentHashMap<>();
return meta;
}
@Override
public UUID getUniqueId() {
return DEFAULT_ID;

View File

@ -19,8 +19,6 @@
package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
@ -30,9 +28,10 @@ import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.NullWorld;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An adapter to adapt a Bukkit entity into a WorldEdit one.

View File

@ -19,8 +19,6 @@
package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.entity.metadata.EntityProperties;
import com.sk89q.worldedit.util.Enums;
import org.bukkit.entity.Ambient;
@ -44,6 +42,8 @@ import org.bukkit.entity.Tameable;
import org.bukkit.entity.Villager;
import org.bukkit.entity.minecart.ExplosiveMinecart;
import static com.google.common.base.Preconditions.checkNotNull;
class BukkitEntityProperties implements EntityProperties {
private static final org.bukkit.entity.EntityType armorStandType =

View File

@ -0,0 +1,18 @@
package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.world.registry.BundledItemRegistry;
import org.bukkit.Material;
import java.util.ArrayList;
import java.util.Collection;
public class BukkitItemRegistry extends BundledItemRegistry {
@Override
public Collection<String> registerItems() {
ArrayList<String> items = new ArrayList<>();
for (Material m : Material.values()) {
if (!m.isLegacy() && m.isItem()) items.add(m.getKey().getNamespace() + ":" + m.getKey().getKey());
}
return items;
}
}

View File

@ -0,0 +1,60 @@
package com.sk89q.worldedit.bukkit;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.bukkit.util.ItemUtil;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.world.item.ItemType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import javax.annotation.Nullable;
public class BukkitItemStack extends BaseItemStack {
private ItemStack stack;
private boolean loadedNBT;
public BukkitItemStack(ItemStack stack) {
super(BukkitAdapter.asItemType(stack.getType()));
this.stack = stack;
}
public BukkitItemStack(ItemType type, ItemStack stack) {
super(type);
this.stack = stack;
}
@Override
public int getAmount() {
return stack.getAmount();
}
@Nullable
@Override
public Object getNativeItem() {
return super.getNativeItem();
}
@Nullable
@Override
public CompoundTag getNbtData() {
if (!loadedNBT) {
loadedNBT = true;
ItemUtil util = Fawe.<FaweBukkit>imp().getItemUtil();
if (util != null) {
super.setNbtData(util.getNBT(stack));
}
}
return super.getNbtData();
}
@Override
public void setNbtData(@Nullable CompoundTag nbtData) {
ItemUtil util = Fawe.<FaweBukkit>imp().getItemUtil();
if (util != null) {
stack = util.setNBT(stack, nbtData);
}
super.setNbtData(nbtData);
}
}

View File

@ -22,7 +22,8 @@ package com.sk89q.worldedit.bukkit;
import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extension.platform.AbstractPlayerActor;
@ -70,7 +71,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
ItemStack itemStack = handSide == HandSide.MAIN_HAND
? player.getInventory().getItemInMainHand()
: player.getInventory().getItemInOffHand();
return BukkitAdapter.asBlockState(itemStack).toBaseBlock();
return new BaseBlock(BukkitAdapter.asBlockState(itemStack));
}
@Override
@ -156,7 +157,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
if (params.length > 0) {
send = send + "|" + StringUtil.joinString(params, "|");
}
player.sendPluginMessage(plugin, WorldEditPlugin.CUI_PLUGIN_CHANNEL, send.getBytes(CUIChannelListener.UTF_8_CHARSET));
player.sendPluginMessage(plugin, WorldEditPlugin.getCuiPluginChannel(), send.getBytes(CUIChannelListener.UTF_8_CHARSET));
}
public Player getPlayer() {

View File

@ -19,18 +19,17 @@
package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.extent.inventory.BlockBagException;
import com.sk89q.worldedit.extent.inventory.OutOfBlocksException;
import com.sk89q.worldedit.extent.inventory.OutOfSpaceException;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.extent.inventory.*;
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.util.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class BukkitPlayerBlockBag extends BlockBag {
public class BukkitPlayerBlockBag extends BlockBag implements SlottableBlockBag {
private Player player;
private ItemStack[] items;
@ -181,4 +180,16 @@ public class BukkitPlayerBlockBag extends BlockBag {
public void addSingleSourcePosition(Location pos) {
}
@Override
public BaseItem getItem(int slot) {
loadInventory();
return BukkitAdapter.adapt(items[slot]);
}
@Override
public void setItem(int slot, BaseItem block) {
loadInventory();
BaseItemStack stack = block instanceof BaseItemStack ? (BaseItemStack) block : new BaseItemStack(block.getType(), block.getNbtData(), 1);
items[slot] = BukkitAdapter.adapt(stack);
}
}

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import com.sk89q.worldedit.world.registry.BlockRegistry;
import com.sk89q.worldedit.world.registry.BundledRegistries;
import com.sk89q.worldedit.world.registry.ItemRegistry;
/**
* World data for the Bukkit platform.
@ -30,6 +31,7 @@ class BukkitRegistries extends BundledRegistries {
private static final BukkitRegistries INSTANCE = new BukkitRegistries();
private final BlockRegistry blockRegistry = new BukkitBlockRegistry();
private final ItemRegistry itemRegistry = new BukkitItemRegistry();
private final BiomeRegistry biomeRegistry = new BukkitBiomeRegistry();
/**
@ -48,6 +50,11 @@ class BukkitRegistries extends BundledRegistries {
return biomeRegistry;
}
@Override
public ItemRegistry getItemRegistry() {
return itemRegistry;
}
/**
* Get a static instance.
*

View File

@ -100,7 +100,7 @@ public class BukkitServerInterface implements MultiUserPlatform {
return player;
} else {
org.bukkit.entity.Player bukkitPlayer = server.getPlayerExact(player.getName());
return bukkitPlayer != null ? new BukkitPlayer(plugin, bukkitPlayer) : null;
return bukkitPlayer != null ? plugin.wrapPlayer(bukkitPlayer) : null;
}
}
@ -177,7 +177,7 @@ public class BukkitServerInterface implements MultiUserPlatform {
public Collection<Actor> getConnectedUsers() {
List<Actor> users = new ArrayList<>();
for (org.bukkit.entity.Player player : Bukkit.getServer().getOnlinePlayers()) {
users.add(new BukkitPlayer(plugin, player));
users.add(plugin.wrapPlayer(player));
}
return users;
}

View File

@ -19,16 +19,12 @@
package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.EditSession;
import com.boydti.fawe.Fawe;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.LazyBlock;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.history.change.BlockChange;
@ -47,19 +43,17 @@ import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Chest;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.DoubleChestInventory;
import org.bukkit.inventory.Inventory;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
public class BukkitWorld extends AbstractWorld {
@ -91,7 +85,7 @@ public class BukkitWorld extends AbstractWorld {
List<com.sk89q.worldedit.entity.Entity> entities = new ArrayList<>();
for (Entity ent : ents) {
if (region.contains(BukkitAdapter.asVector(ent.getLocation()))) {
entities.add(BukkitAdapter.adapt(ent));
addEntities(ent, entities);
}
}
return entities;
@ -101,11 +95,43 @@ public class BukkitWorld extends AbstractWorld {
public List<com.sk89q.worldedit.entity.Entity> getEntities() {
List<com.sk89q.worldedit.entity.Entity> list = new ArrayList<>();
for (Entity entity : getWorld().getEntities()) {
list.add(BukkitAdapter.adapt(entity));
addEntities(entity, list);
}
return list;
}
private static com.sk89q.worldedit.entity.Entity adapt(Entity ent) {
if (ent == null) return null;
return BukkitAdapter.adapt(ent);
}
private void addEntities(Entity ent, Collection<com.sk89q.worldedit.entity.Entity> ents) {
ents.add(BukkitAdapter.adapt(ent));
if (ent instanceof Player) {
final Player plr = (Player) ent;
com.sk89q.worldedit.entity.Entity left = adapt(((Player) ent).getShoulderEntityLeft());
com.sk89q.worldedit.entity.Entity right = adapt(((Player) ent).getShoulderEntityRight());
if (left != null) {
ents.add(new DelegateEntity(left) {
@Override
public boolean remove() {
plr.setShoulderEntityLeft(null);
return true;
}
});
}
if (right != null) {
ents.add(new DelegateEntity(right) {
@Override
public boolean remove() {
plr.setShoulderEntityRight(null);
return true;
}
});
}
}
}
@Nullable
@Override
public com.sk89q.worldedit.entity.Entity createEntity(com.sk89q.worldedit.util.Location location, BaseEntity entity) {
@ -165,7 +191,7 @@ public class BukkitWorld extends AbstractWorld {
@Override
public boolean regenerate(Region region, EditSession editSession) {
BlockStateHolder[] history = new BlockStateHolder[16 * 16 * (getMaxY() + 1)];
com.sk89q.worldedit.world.block.BlockStateHolder[] history = new com.sk89q.worldedit.world.block.BlockState[16 * 16 * (getMaxY() + 1)];
for (Vector2D chunk : region.getChunks()) {
Vector min = new Vector(chunk.getBlockX() * 16, 0, chunk.getBlockZ() * 16);
@ -415,15 +441,15 @@ public class BukkitWorld extends AbstractWorld {
}
@Override
public boolean setBlock(Vector position, BlockStateHolder block, boolean notifyAndLight) throws WorldEditException {
public boolean setBlock(Vector position, BlockStateHolder block, boolean notifyAndLight) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
try {
return adapter.setBlock(BukkitAdapter.adapt(getWorld(), position), block, notifyAndLight);
} catch (Exception e) {
if (block instanceof BaseBlock && ((BaseBlock) block).getNbtData() != null) {
if (block.getNbtData() != null) {
logger.warning("Tried to set a corrupt tile entity at " + position.toString());
logger.warning(((BaseBlock) block).getNbtData().toString());
logger.warning(block.getNbtData().toString());
}
e.printStackTrace();
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
@ -432,18 +458,23 @@ public class BukkitWorld extends AbstractWorld {
}
} else {
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
bukkitBlock.setBlockData(BukkitAdapter.adapt(block), notifyAndLight);
bukkitBlock.setBlockData(BukkitAdapter.adapt(block), false);
return true;
}
}
@Override
public BaseBlock getFullBlock(Vector position) {
public com.sk89q.worldedit.world.block.BlockState getLazyBlock(Vector position) {
return getBlock(position);
}
@Override
public com.sk89q.worldedit.world.block.BlockState getFullBlock(Vector position) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
return adapter.getBlock(BukkitAdapter.adapt(getWorld(), position));
} else {
return getBlock(position).toBaseBlock();
return getBlock(position);
}
}

View File

@ -0,0 +1,105 @@
package com.sk89q.worldedit.bukkit;
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.isBlock() && !material.isLegacy()) {
NamespacedKey key = material.getKey();
blockTypes[i] = BlockTypes.get(key.getNamespace() + ":" + key.getKey());
} else if (material.isItem() && !material.isLegacy()) {
itemTypes[i] = ItemTypes.get(material.getKey().toString());
}
}
}
/**
* 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

@ -0,0 +1,47 @@
package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.util.Location;
import javax.annotation.Nullable;
public class DelegateEntity implements Entity {
private final Entity parent;
public DelegateEntity(Entity parent) {
this.parent = parent;
}
public Entity getParent() {
return parent;
}
@Override
@Nullable
public BaseEntity getState() {
return parent.getState();
}
@Override
public Location getLocation() {
return parent.getLocation();
}
@Override
public Extent getExtent() {
return parent.getExtent();
}
@Override
public boolean remove() {
return parent.remove();
}
@Override
@Nullable
public <T> T getFacet(Class<? extends T> cls) {
return parent.getFacet(cls);
}
}

View File

@ -21,6 +21,11 @@ package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import com.bekvon.bukkit.residence.commands.message;
import com.bekvon.bukkit.residence.containers.cmd;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.bukkit.adapter.Spigot_v1_13_R1;
import com.google.common.base.Joiner;
import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.wepif.PermissionsResolverManager;
@ -35,20 +40,30 @@ 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;
import com.sk89q.worldedit.extension.platform.NoCapablePlatformException;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.world.registry.LegacyMapper;
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.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -62,13 +77,62 @@ import javax.annotation.Nullable;
public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
private static final Logger log = Logger.getLogger(WorldEditPlugin.class.getCanonicalName());
public static final String CUI_PLUGIN_CHANNEL = "worldedit:cui";
private static final String CUI_PLUGIN_CHANNEL = "worldedit:cui";
private static WorldEditPlugin INSTANCE;
private BukkitImplAdapter bukkitAdapter;
private BukkitServerInterface server;
private BukkitConfiguration config;
private static Map<String, Plugin> lookupNames;
static {
{ // Disable AWE as otherwise both fail to load
PluginManager manager = Bukkit.getPluginManager();
try {
Field pluginsField = manager.getClass().getDeclaredField("plugins");
Field lookupNamesField = manager.getClass().getDeclaredField("lookupNames");
pluginsField.setAccessible(true);
lookupNamesField.setAccessible(true);
List<Plugin> plugins = (List<Plugin>) pluginsField.get(manager);
lookupNames = (Map<String, Plugin>) lookupNamesField.get(manager);
pluginsField.set(manager, plugins = new ArrayList<Plugin>(plugins) {
@Override
public boolean add(Plugin plugin) {
if (plugin.getName().startsWith("AsyncWorldEdit")) {
Fawe.debug("Disabling `" + plugin.getName() + "` as it is incompatible");
} else if (plugin.getName().startsWith("BetterShutdown")) {
Fawe.debug("Disabling `" + plugin.getName() + "` as it is incompatible (Improperly shaded classes from com.sk89q.minecraft.util.commands)");
} else {
return super.add(plugin);
}
return false;
}
});
lookupNamesField.set(manager, lookupNames = new ConcurrentHashMap<String, Plugin>(lookupNames) {
@Override
public Plugin put(String key, Plugin plugin) {
if (plugin.getName().startsWith("AsyncWorldEdit") || plugin.getName().startsWith("BetterShutdown")) {
return null;
}
return super.put(key, plugin);
}
});
} catch (Throwable ignore) {}
}
}
public WorldEditPlugin() {
if (lookupNames != null) lookupNames.putIfAbsent("WorldEdit".toLowerCase(Locale.ENGLISH), this);
}
public WorldEditPlugin(JavaPluginLoader loader, PluginDescriptionFile desc, File dataFolder, File jarFile) {
if (lookupNames != null) lookupNames.putIfAbsent("WorldEdit".toLowerCase(Locale.ENGLISH), this);
}
public static String getCuiPluginChannel() {
return CUI_PLUGIN_CHANNEL;
}
/**
* Called on plugin enable.
*/
@ -76,6 +140,7 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
@Override
public void onEnable() {
this.INSTANCE = this;
FaweBukkit imp = new FaweBukkit(this);
//noinspection ResultOfMethodCallIgnored
getDataFolder().mkdirs();
@ -90,11 +155,14 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
worldEdit.loadMappings();
loadConfig(); // Load configuration
PermissionsResolverManager.initialize(this); // Setup permission resolver
fail(() -> PermissionsResolverManager.initialize(INSTANCE), "Failed to initialize permissions resolver");
// Register CUI
getServer().getMessenger().registerIncomingPluginChannel(this, CUI_PLUGIN_CHANNEL, new CUIChannelListener(this));
getServer().getMessenger().registerOutgoingPluginChannel(this, CUI_PLUGIN_CHANNEL);
fail(() -> {
getServer().getMessenger().registerIncomingPluginChannel(INSTANCE, CUI_PLUGIN_CHANNEL, new CUIChannelListener(INSTANCE));
getServer().getMessenger().registerOutgoingPluginChannel(INSTANCE, CUI_PLUGIN_CHANNEL);
}, "Failed to register CUI");
// Now we can register events
getServer().getPluginManager().registerEvents(new WorldEditListener(this), this);
@ -103,13 +171,35 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
// Forge WorldEdit and there's (probably) not going to be any other
// platforms to be worried about... at the current time of writing
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
{ // Register 1.13 Material ids with LegacyMapper
LegacyMapper legacyMapper = LegacyMapper.getInstance();
for (Material m : Material.values()) {
if (!m.isLegacy() && m.isBlock()) {
legacyMapper.register(m.getId(), 0, BukkitAdapter.adapt(m).getDefaultState());
}
}
}
}
private void fail(Runnable run, String message) {
try {
run.run();
} catch (Throwable e) {
log.log(Level.SEVERE, message);
e.printStackTrace();
}
}
private void loadConfig() {
createDefaultConfiguration("config.yml"); // Create the default configuration file
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "config.yml"), true), this);
config.load();
createDefaultConfiguration("config-legacy.yml"); // Create the default configuration file
try {
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "config-legacy.yml"), true), this);
config.load();
} catch (Throwable e) {
log.log(Level.SEVERE, "Failed to load config.yml");
e.printStackTrace();
}
}
private void loadAdapter() {
@ -117,6 +207,7 @@ 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.addFromPath(getClass().getClassLoader());
@ -133,14 +224,18 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
bukkitAdapter = adapterLoader.loadAdapter();
log.log(Level.INFO, "Using " + bukkitAdapter.getClass().getCanonicalName() + " as the Bukkit adapter");
} catch (AdapterLoadException e) {
Platform platform = worldEdit.getPlatformManager().queryCapability(Capability.WORLD_EDITING);
if (platform instanceof BukkitServerInterface) {
log.log(Level.WARNING, e.getMessage());
} else {
log.log(Level.INFO, "WorldEdit could not find a Bukkit adapter for this MC version, " +
"but it seems that you have another implementation of WorldEdit installed (" + platform.getPlatformName() + ") " +
"that handles the world editing.");
}
try {
Platform platform = worldEdit.getPlatformManager().queryCapability(Capability.WORLD_EDITING);
if (platform instanceof BukkitServerInterface) {
log.log(Level.WARNING, e.getMessage());
return;
} else {
log.log(Level.INFO, "WorldEdit could not find a Bukkit adapter for this MC version, " +
"but it seems that you have another implementation of WorldEdit installed (" + platform.getPlatformName() + ") " +
"that handles the world editing.");
}
} catch (NoCapablePlatformException ignore) {}
log.log(Level.INFO, "WorldEdit could not find a Bukkit adapter for this MC version");
}
}
@ -149,6 +244,7 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
*/
@Override
public void onDisable() {
Fawe.get().onDisable();
WorldEdit worldEdit = WorldEdit.getInstance();
worldEdit.getSessionManager().clear();
worldEdit.getPlatformManager().unregister(server);
@ -342,7 +438,7 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
* @return an instance of the plugin
* @throws NullPointerException if the plugin hasn't been enabled
*/
static WorldEditPlugin getInstance() {
public static WorldEditPlugin getInstance() {
return checkNotNull(INSTANCE);
}
@ -352,7 +448,7 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
* @return the adapter
*/
@Nullable
BukkitImplAdapter getBukkitImplAdapter() {
public BukkitImplAdapter getBukkitImplAdapter() {
return bukkitAdapter;
}

View File

@ -19,11 +19,15 @@
package com.sk89q.worldedit.bukkit.adapter;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.blocks.BaseBlock;
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.Location;
import org.bukkit.block.Biome;
import org.bukkit.entity.Entity;
@ -35,7 +39,7 @@ import javax.annotation.Nullable;
/**
* An interface for adapters of various Bukkit implementations.
*/
public interface BukkitImplAdapter {
public interface BukkitImplAdapter<T> {
/**
* Get the biome ID for the given biome.
@ -63,7 +67,7 @@ public interface BukkitImplAdapter {
* @param location the location
* @return the block
*/
BaseBlock getBlock(Location location);
BlockState getBlock(Location location);
/**
* Set the block at the given location.
@ -101,4 +105,12 @@ public interface BukkitImplAdapter {
* @return The properties map
*/
Map<String, ? extends Property> getProperties(BlockType blockType);
default Tag toNative(T foreign) {
return null;
}
default T fromNative(Tag foreign) {
return null;
}
}

View File

@ -77,6 +77,10 @@ public class BukkitImplLoader {
}
}
public void addClass(Class cls) {
adapterCandidates.add(0, cls.getName());
}
/**
* Search the given JAR for candidate implementations.
*