Merge remote-tracking branch 'upstream/master' into merge

This commit is contained in:
Jesse Boyd
2019-11-19 21:23:47 +00:00
272 changed files with 16041 additions and 6107 deletions

View File

@ -31,6 +31,7 @@ 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.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.extension.platform.PlayerProxy;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
@ -51,15 +52,431 @@ import com.sk89q.worldedit.world.item.ItemTypes;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.Objects;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import java.util.EnumMap;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Adapts between Bukkit and WorldEdit equivalent objects.
*/
public class BukkitAdapter {
private BukkitAdapter() {
}
private static final ParserContext TO_BLOCK_CONTEXT = new ParserContext();
static {
TO_BLOCK_CONTEXT.setRestricted(false);
}
/**
* 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());
}
/**
* 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;
}
}
/**
* 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);
}
/**
* 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.
*
* @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.getName());
}
}
}
/**
* 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);
Vector3 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
*/
public static org.bukkit.Location adapt(Location location) {
checkNotNull(location);
Vector3 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
*/
public static org.bukkit.Location adapt(org.bukkit.World world, Vector3 position) {
checkNotNull(world);
checkNotNull(position);
return new org.bukkit.Location(
world,
position.getX(), position.getY(), position.getZ());
}
/**
* 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, BlockVector3 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
*/
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());
}
/**
* Create a WorldEdit Vector from a Bukkit location.
*
* @param location The Bukkit location
* @return a WorldEdit vector
*/
public static Vector3 asVector(org.bukkit.Location location) {
checkNotNull(location);
return Vector3.at(location.getX(), location.getY(), location.getZ());
}
/**
* Create a WorldEdit BlockVector from a Bukkit location.
*
* @param location The Bukkit location
* @return a WorldEdit vector
*/
public static BlockVector3 asBlockVector(org.bukkit.Location location) {
checkNotNull(location);
return BlockVector3.at(location.getX(), location.getY(), location.getZ());
}
/**
* 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);
}
/**
* 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(Locale.ROOT));
}
/**
* 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");
}
return Material.getMaterial(blockType.getId().substring(10).toUpperCase(Locale.ROOT));
}
/**
* 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(Locale.ROOT));
}
/**
* Create a WorldEdit BiomeType from a Bukkit one.
*
* @param biome Bukkit Biome
* @return WorldEdit BiomeType
*/
public static BiomeType adapt(Biome biome) {
return BiomeTypes.get(biome.name().toLowerCase(Locale.ROOT));
}
public static Biome adapt(BiomeType biomeType) {
if (!biomeType.getId().startsWith("minecraft:")) {
throw new IllegalArgumentException("Bukkit only supports vanilla biomes");
}
try {
return Biome.valueOf(biomeType.getId().substring(10).toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException e) {
return null;
}
}
/**
* Create a WorldEdit EntityType from a Bukkit one.
*
* @param entityType Bukkit EntityType
* @return WorldEdit EntityType
*/
public static EntityType adapt(org.bukkit.entity.EntityType entityType) {
final String name = entityType.getName();
if (name == null) {
return null;
}
return EntityTypes.get(name.toLowerCase(Locale.ROOT));
}
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));
}
private static EnumMap<Material, BlockType> materialBlockTypeCache = new EnumMap<>(Material.class);
private static EnumMap<Material, ItemType> materialItemTypeCache = new EnumMap<>(Material.class);
/**
* Converts a Material to a BlockType
*
* @param material The material
* @return The blocktype
*/
@Nullable
public static BlockType asBlockType(Material material) {
checkNotNull(material);
return materialBlockTypeCache.computeIfAbsent(material, input -> BlockTypes.get(material.getKey().toString()));
}
/**
* Converts a Material to a ItemType
*
* @param material The material
* @return The itemtype
*/
@Nullable
public static ItemType asItemType(Material material) {
checkNotNull(material);
return materialItemTypeCache.computeIfAbsent(material, input -> ItemTypes.get(material.getKey().toString()));
}
private static Int2ObjectMap<BlockState> blockStateCache = new Int2ObjectOpenHashMap<>();
private static Map<String, BlockState> blockStateStringCache = new HashMap<>();
/**
* Create a WorldEdit BlockState from a Bukkit BlockData
*
* @param blockData The Bukkit BlockData
* @return The WorldEdit BlockState
*/
public static BlockState adapt(BlockData blockData) {
checkNotNull(blockData);
if (WorldEditPlugin.getInstance().getBukkitImplAdapter() == null) {
return blockStateStringCache.computeIfAbsent(blockData.getAsString(), input -> {
try {
return WorldEdit.getInstance().getBlockFactory().parseFromInput(input, TO_BLOCK_CONTEXT).toImmutableState();
} catch (InputParseException e) {
e.printStackTrace();
return null;
}
});
} else {
return blockStateCache.computeIfAbsent(
WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBlockStateId(blockData).orElseGet(
() -> blockData.getAsString().hashCode()
), input -> {
try {
return WorldEdit.getInstance().getBlockFactory().parseFromInput(blockData.getAsString(), TO_BLOCK_CONTEXT).toImmutableState();
} catch (InputParseException e) {
e.printStackTrace();
return null;
}
});
}
}
private static Int2ObjectMap<BlockData> blockDataCache = new Int2ObjectOpenHashMap<>();
/**
* Create a Bukkit BlockData from a WorldEdit BlockStateHolder
*
* @param block The WorldEdit BlockStateHolder
* @return The Bukkit BlockData
*/
public static <B extends BlockStateHolder<B>> BlockData adapt(B block) {
checkNotNull(block);
// Should never not have an ID for this BlockState.
int cacheKey = BlockStateIdAccess.getBlockStateId(block.toImmutableState()).orElseGet(block::hashCode);
return blockDataCache.computeIfAbsent(cacheKey, input -> Bukkit.createBlockData(block.getAsString())).clone();
}
/**
* Create a WorldEdit BlockState from a Bukkit ItemStack
*
* @param itemStack The Bukkit ItemStack
* @return The WorldEdit BlockState
*/
public static BlockState asBlockState(ItemStack itemStack) throws WorldEditException {
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
*/
public static BaseItemStack adapt(ItemStack itemStack) {
checkNotNull(itemStack);
if (WorldEditPlugin.getInstance().getBukkitImplAdapter() != null) {
return WorldEditPlugin.getInstance().getBukkitImplAdapter().adapt(itemStack);
}
return new BaseItemStack(ItemTypes.get(itemStack.getType().getKey().toString()), itemStack.getAmount());
}
/**
* 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 (WorldEditPlugin.getInstance().getBukkitImplAdapter() != null) {
return WorldEditPlugin.getInstance().getBukkitImplAdapter().adapt(item);
}
return new ItemStack(adapt(item.getType()), item.getAmount());
}
}
/**
* Adapts between Bukkit and WorldEdit equivalent objects.
*/

View File

@ -19,7 +19,6 @@
package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.registry.Category;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BlockCategoryRegistry;
import org.bukkit.Bukkit;
@ -44,9 +43,4 @@ public class BukkitBlockCategoryRegistry implements BlockCategoryRegistry {
Tag<Material> tag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, new NamespacedKey(namespace, key), Material.class);
return getFromBukkitTag(tag);
}
@Override
public Set<BlockType> getAll(Category<BlockType> category) {
return getCategorisedByName(category.getId());
}
}

View File

@ -75,6 +75,13 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
return super.getMaterial(state);
}
@Override
public OptionalInt getInternalBlockStateId(BlockState state) {
if (WorldEditPlugin.getInstance().getBukkitImplAdapter() != null) {
return WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBlockStateId(state);
}
return OptionalInt.empty();
}
@Nullable
@Override
public Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
@ -137,9 +144,4 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
}
return blocks;
}
@Override
public OptionalInt getInternalBlockStateId(BlockState state) {
return WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBlockStateId(state);
}
}

View File

@ -106,10 +106,6 @@ public class BukkitCommandSender extends AbstractNonPlayerActor {
return true;
}
@Override public boolean togglePermission(String permission) {
return false;
}
@Override public void setPermission(String permission, boolean value) {
}

View File

@ -19,7 +19,6 @@
package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.registry.Category;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.ItemCategoryRegistry;
import org.bukkit.Bukkit;
@ -44,9 +43,4 @@ public class BukkitItemCategoryRegistry implements ItemCategoryRegistry {
Tag<Material> tag = Bukkit.getTag(Tag.REGISTRY_ITEMS, new NamespacedKey(namespace, key), Material.class);
return getFromBukkitTag(tag);
}
@Override
public Set<ItemType> getAll(Category<ItemType> category) {
return getCategorisedByName(category.getId());
}
}

View File

@ -44,6 +44,8 @@ import com.sk89q.worldedit.util.formatting.text.adapter.bukkit.TextAdapter;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import java.util.Locale;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.gamemode.GameModes;
@ -59,7 +61,6 @@ import org.bukkit.inventory.PlayerInventory;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@ -215,12 +216,12 @@ public class BukkitPlayer extends AbstractPlayerActor {
@Override
public GameMode getGameMode() {
return GameModes.get(getPlayer().getGameMode().name().toLowerCase(Locale.ROOT));
return GameModes.get(player.getGameMode().name().toLowerCase(Locale.ROOT));
}
@Override
public void setGameMode(GameMode gameMode) {
getPlayer().setGameMode(org.bukkit.GameMode.valueOf(gameMode.getId().toUpperCase(Locale.ROOT)));
player.setGameMode(org.bukkit.GameMode.valueOf(gameMode.getId().toUpperCase(Locale.ROOT)));
}
@Override
@ -239,6 +240,16 @@ public class BukkitPlayer extends AbstractPlayerActor {
}
}
@Override
public boolean isAllowedToFly() {
return player.getAllowFlight();
}
@Override
public void setFlying(boolean flying) {
player.setFlying(flying);
}
@Override
public void setPermission(String permission, boolean value) {
/*
@ -281,16 +292,6 @@ public class BukkitPlayer extends AbstractPlayerActor {
return player;
}
@Override
public boolean isAllowedToFly() {
return getPlayer().getAllowFlight();
}
@Override
public void setFlying(boolean flying) {
getPlayer().setFlying(flying);
}
@Override
public BaseEntity getState() {
throw new UnsupportedOperationException("Cannot create a state from this object");

View File

@ -41,8 +41,8 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.bukkit.Bukkit;
import javax.annotation.Nullable;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.EntityType;

View File

@ -34,6 +34,7 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
@ -43,6 +44,7 @@ import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.AbstractWorld;
import com.sk89q.worldedit.world.biome.BiomeType;
@ -328,19 +330,27 @@ public class BukkitWorld extends AbstractWorld {
@Override
public void checkLoadedChunk(BlockVector3 pt) {
World world = getWorld();
int X = pt.getBlockX() >> 4;
int Z = pt.getBlockZ() >> 4;
if (Fawe.isMainThread()) {
world.getChunkAt(X, Z);
} else if (!world.isChunkLoaded(X, Z)) {
if (PaperLib.isPaper()) {
world.getChunkAtAsync(X, Z, true);
} else {
Fawe.get().getQueueHandler().sync(() -> {
world.getChunkAt(X, Z);
});
}
world.getChunkAt(pt.getBlockX() >> 4, pt.getBlockZ() >> 4);
if (!world.isChunkLoaded(pt.getBlockX() >> 4, pt.getBlockZ() >> 4)) {
world.loadChunk(pt.getBlockX() >> 4, pt.getBlockZ() >> 4);
}
if (!world.isChunkLoaded(pt.getBlockX() >> 4, pt.getBlockZ() >> 4)) {
int X = pt.getBlockX() >> 4;
int Z = pt.getBlockZ() >> 4;
if (Fawe.isMainThread()) {
world.getChunkAt(X, Z);
} else if (!world.isChunkLoaded(X, Z)) {
if (PaperLib.isPaper()) {
world.getChunkAtAsync(X, Z, true);
} else {
Fawe.get().getQueueHandler().sync(() -> {
world.getChunkAt(X, Z);
});
}
}
}
}
@Override
@ -552,4 +562,14 @@ public class BukkitWorld extends AbstractWorld {
org.bukkit.entity.Player bukkitPlayer = BukkitAdapter.adapt(player);
WorldEditPlugin.getInstance().getBukkitImplAdapter().sendFakeChunk(getWorld(), bukkitPlayer, packet);
}
@Override
public boolean useItem(BlockVector3 position, BaseItem item, Direction face) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
return adapter.simulateItemUse(getWorld(), position, item, face);
}
return false;
}
}

View File

@ -26,7 +26,6 @@ import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import java.util.Optional;
import org.bukkit.block.Block;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
@ -42,6 +41,8 @@ import org.enginehub.piston.inject.InjectedValueStore;
import org.enginehub.piston.inject.Key;
import org.enginehub.piston.inject.MapBackedValueStore;
import java.util.Optional;
/**
* Handles all events thrown in relation to a Player
*/

View File

@ -183,8 +183,8 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
if (Files.exists(delChunks)) {
ChunkDeleter.runFromFile(delChunks, true);
}
fail(() -> PermissionsResolverManager.initialize(INSTANCE), "Failed to initialize permissions resolver");
fail(() -> PermissionsResolverManager.initialize(INSTANCE), "Failed to initialize permissions resolver");
}
/**
@ -341,6 +341,20 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
}
}
@Override
public List<String> onTabComplete(CommandSender sender, Command cmd, String commandLabel, String[] args) {
// Add the command to the array because the underlying command handling
// code of WorldEdit expects it
String[] split = new String[args.length + 1];
System.arraycopy(args, 0, split, 1, args.length);
split[0] = "/" + commandLabel;
String arguments = Joiner.on(" ").join(split);
CommandSuggestionEvent event = new CommandSuggestionEvent(wrapCommandSender(sender), arguments);
getWorldEdit().getEventBus().post(event);
return CommandUtil.fixSuggestions(arguments, event.getSuggestions());
}
private void fail(Runnable run, String message) {
try {
run.run();