some adapter refactoring

This commit is contained in:
Jesse Boyd 2019-11-19 04:40:40 +00:00
parent 751765cc01
commit 1b07846746
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
30 changed files with 1855 additions and 4779 deletions

View File

@ -0,0 +1,53 @@
package com.boydti.fawe.bukkit.adapter;
import com.boydti.fawe.beta.IBlocks;
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.math.BlockVector3;
import net.minecraft.server.v1_14_R1.WorldServer;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public abstract class MapChunkUtil<T> {
protected Field fieldX;
protected Field fieldZ;
protected Field fieldHeightMap;
protected Field fieldBitMask;
protected Field fieldChunkData;
protected Field fieldBlockEntities;
protected Field fieldFull;
public abstract T createPacket();
public T create(BukkitImplAdapter adapter, ChunkPacket packet) {
try {
T nmsPacket;
int bitMask = packet.getChunk().getBitMask();
nmsPacket = createPacket();
fieldX.setInt(nmsPacket, packet.getChunkX());
fieldZ.setInt(nmsPacket, packet.getChunkZ());
fieldBitMask.set(nmsPacket, packet.getChunk().getBitMask());
Object heightMap = adapter.fromNative(packet.getHeightMap());
fieldHeightMap.set(nmsPacket, heightMap);
fieldChunkData.set(nmsPacket, packet.getSectionBytes());
Map<BlockVector3, CompoundTag> tiles = packet.getChunk().getTiles();
ArrayList<Object> nmsTiles = new ArrayList<>(tiles.size());
for (Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
Object nmsTag = adapter.fromNative(entry.getValue());
nmsTiles.add(nmsTag);
}
fieldBlockEntities.set(nmsPacket, nmsTiles);
fieldFull.set(nmsPacket, packet.isFull());
return nmsPacket;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,93 @@
package com.boydti.fawe.bukkit.adapter;
import com.sk89q.worldedit.world.block.BlockID;
import net.minecraft.server.v1_14_R1.ChunkSection;
import java.util.function.Function;
public class NMSAdapter<T> {
public static int createPalette(int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy, int[] num_palette_buffer, char[] set) {
int air = 0;
int num_palette = 0;
for (int i = 0; i < 4096; i++) {
char ordinal = set[i];
switch (ordinal) {
case 0:
ordinal = BlockID.AIR;
case BlockID.AIR:
case BlockID.CAVE_AIR:
case BlockID.VOID_AIR:
air++;
}
int palette = blockToPalette[ordinal];
if (palette == Integer.MAX_VALUE) {
blockToPalette[ordinal] = palette = num_palette;
paletteToBlock[num_palette] = ordinal;
num_palette++;
}
blocksCopy[i] = palette;
}
num_palette_buffer[0] = num_palette;
return air;
}
public static int createPalette(int layer, int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy, int[] num_palette_buffer, Function<Integer, char[]> get, char[] set) {
int air = 0;
int num_palette = 0;
int i = 0;
outer:
for (; i < 4096; i++) {
char ordinal = set[i];
switch (ordinal) {
case BlockID.__RESERVED__:
break outer;
case BlockID.AIR:
case BlockID.CAVE_AIR:
case BlockID.VOID_AIR:
air++;
}
int palette = blockToPalette[ordinal];
if (palette == Integer.MAX_VALUE) {
blockToPalette[ordinal] = palette = num_palette;
paletteToBlock[num_palette] = ordinal;
num_palette++;
}
blocksCopy[i] = palette;
}
if (i != 4096) {
char[] getArr = get.apply(layer);
for (; i < 4096; i++) {
char ordinal = set[i];
switch (ordinal) {
case BlockID.__RESERVED__:
ordinal = getArr[i];
switch (ordinal) {
case BlockID.__RESERVED__:
ordinal = BlockID.AIR;
case BlockID.AIR:
case BlockID.CAVE_AIR:
case BlockID.VOID_AIR:
air++;
default:
set[i] = ordinal;
}
break;
case BlockID.AIR:
case BlockID.CAVE_AIR:
case BlockID.VOID_AIR:
air++;
}
int palette = blockToPalette[ordinal];
if (palette == Integer.MAX_VALUE) {
blockToPalette[ordinal] = palette = num_palette;
paletteToBlock[num_palette] = ordinal;
num_palette++;
}
blocksCopy[i] = palette;
}
}
num_palette_buffer[0] = num_palette;
return air;
}
}

View File

@ -2,15 +2,13 @@ package com.boydti.fawe.bukkit.adapter.mc1_14;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.bukkit.adapter.NMSAdapter;
import com.boydti.fawe.bukkit.adapter.DelegateLock;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.collection.BitArray4096;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.worldedit.world.block.BlockID;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache;
import io.papermc.lib.PaperLib;
import net.jpountz.util.UnsafeUtils;
@ -24,7 +22,6 @@ import net.minecraft.server.v1_14_R1.DataPaletteBlock;
import net.minecraft.server.v1_14_R1.DataPaletteLinear;
import net.minecraft.server.v1_14_R1.GameProfileSerializer;
import net.minecraft.server.v1_14_R1.IBlockData;
import net.minecraft.server.v1_14_R1.PacketPlayOutMapChunk;
import net.minecraft.server.v1_14_R1.PlayerChunk;
import net.minecraft.server.v1_14_R1.PlayerChunkMap;
import org.bukkit.craftbukkit.v1_14_R1.CraftChunk;
@ -35,16 +32,13 @@ import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.locks.Lock;
import java.util.function.Function;
import java.util.function.Supplier;
public final class BukkitAdapter_1_14 {
public final class BukkitAdapter_1_14 extends NMSAdapter {
/*
NMS fields
*/
NMS fields
*/
public final static Field fieldBits;
public final static Field fieldPalette;
public final static Field fieldSize;
@ -152,10 +146,6 @@ public final class BukkitAdapter_1_14 {
try {
CraftChunk chunk = (CraftChunk) future.get();
return chunk.getHandle();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (Throwable e) {
e.printStackTrace();
}
@ -178,34 +168,25 @@ public final class BukkitAdapter_1_14 {
if (playerChunk == null) {
return;
}
// ChunkSection[] sections = nmsChunk.getSections();
// for (int layer = 0; layer < 16; layer++) {
// if (sections[layer] == null && (mask & (1 << layer)) != 0) {
// sections[layer] = new ChunkSection(layer << 4);
// }
// }
if (playerChunk.hasBeenLoaded()) {
TaskManager.IMP.sync(new Supplier<Object>() {
@Override
public Object get() {
try {
int dirtyBits = fieldDirtyBits.getInt(playerChunk);
if (dirtyBits == 0) {
nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk);
}
if (mask == 0) {
dirtyBits = 65535;
} else {
dirtyBits |= mask;
}
fieldDirtyBits.set(playerChunk, dirtyBits);
fieldDirtyCount.set(playerChunk, 64);
} catch (IllegalAccessException e) {
e.printStackTrace();
TaskManager.IMP.sync(() -> {
try {
int dirtyBits = fieldDirtyBits.getInt(playerChunk);
if (dirtyBits == 0) {
nmsWorld.getChunkProvider().playerChunkMap.a(playerChunk);
}
return null;
if (mask == 0) {
dirtyBits = 65535;
} else {
dirtyBits |= mask;
}
fieldDirtyBits.set(playerChunk, dirtyBits);
fieldDirtyCount.set(playerChunk, 64);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
});
return;
}
@ -219,90 +200,6 @@ public final class BukkitAdapter_1_14 {
return newChunkSection(layer, null, blocks);
}
private static int createPalette(int layer, int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy, int[] num_palette_buffer, Function<Integer, char[]> get, char[] set) {
int air = 0;
int num_palette = 0;
int i = 0;
outer:
for (; i < 4096; i++) {
char ordinal = set[i];
switch (ordinal) {
case BlockID.__RESERVED__:
break outer;
case BlockID.AIR:
case BlockID.CAVE_AIR:
case BlockID.VOID_AIR:
air++;
}
int palette = blockToPalette[ordinal];
if (palette == Integer.MAX_VALUE) {
blockToPalette[ordinal] = palette = num_palette;
paletteToBlock[num_palette] = ordinal;
num_palette++;
}
blocksCopy[i] = palette;
}
if (i != 4096) {
char[] getArr = get.apply(layer);
for (; i < 4096; i++) {
char ordinal = set[i];
switch (ordinal) {
case BlockID.__RESERVED__:
ordinal = getArr[i];
switch (ordinal) {
case BlockID.__RESERVED__:
ordinal = BlockID.AIR;
case BlockID.AIR:
case BlockID.CAVE_AIR:
case BlockID.VOID_AIR:
air++;
default:
set[i] = ordinal;
}
break;
case BlockID.AIR:
case BlockID.CAVE_AIR:
case BlockID.VOID_AIR:
air++;
}
int palette = blockToPalette[ordinal];
if (palette == Integer.MAX_VALUE) {
blockToPalette[ordinal] = palette = num_palette;
paletteToBlock[num_palette] = ordinal;
num_palette++;
}
blocksCopy[i] = palette;
}
}
num_palette_buffer[0] = num_palette;
return air;
}
private static int createPalette(int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy, int[] num_palette_buffer, char[] set) {
int air = 0;
int num_palette = 0;
for (int i = 0; i < 4096; i++) {
char ordinal = set[i];
switch (ordinal) {
case 0:
ordinal = BlockID.AIR;
case BlockID.AIR:
case BlockID.CAVE_AIR:
case BlockID.VOID_AIR:
air++;
}
int palette = blockToPalette[ordinal];
if (palette == Integer.MAX_VALUE) {
blockToPalette[ordinal] = palette = num_palette;
paletteToBlock[num_palette] = ordinal;
num_palette++;
}
blocksCopy[i] = palette;
}
num_palette_buffer[0] = num_palette;
return air;
}
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set) {
if (set == null) {
return newChunkSection(layer);

View File

@ -39,7 +39,6 @@ import java.util.concurrent.Future;
import java.util.function.Function;
import javax.annotation.Nullable;
import net.minecraft.server.v1_14_R1.BiomeBase;
import net.minecraft.server.v1_14_R1.Block;
import net.minecraft.server.v1_14_R1.BlockPosition;
import net.minecraft.server.v1_14_R1.Chunk;
import net.minecraft.server.v1_14_R1.ChunkSection;
@ -521,7 +520,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
lock.setModified(false);
// Efficiently convert ChunkSection to raw data
try {
Spigot_v1_14_R4 adapter = ((Spigot_v1_14_R4) WorldEditPlugin.getInstance().getBukkitImplAdapter());
FAWE_Spigot_v1_14_R4 adapter = ((FAWE_Spigot_v1_14_R4) WorldEditPlugin.getInstance().getBukkitImplAdapter());
final DataPaletteBlock<IBlockData> blocks = section.getBlocks();
final DataBits bits = (DataBits) BukkitAdapter_1_14.fieldBits.get(blocks);
@ -599,7 +598,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
}
}
private final char ordinal(IBlockData ibd, Spigot_v1_14_R4 adapter) {
private final char ordinal(IBlockData ibd, FAWE_Spigot_v1_14_R4 adapter) {
if (ibd == null) {
return BlockTypes.AIR.getDefaultState().getOrdinalChar();
} else {

View File

@ -0,0 +1,346 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.boydti.fawe.bukkit.adapter.mc1_14;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.TileEntityBlock;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.CachedBukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.IDelegateBukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.impl.Spigot_v1_14_R4;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.LazyBaseEntity;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import net.minecraft.server.v1_14_R1.Block;
import net.minecraft.server.v1_14_R1.BlockPosition;
import net.minecraft.server.v1_14_R1.Chunk;
import net.minecraft.server.v1_14_R1.ChunkCoordIntPair;
import net.minecraft.server.v1_14_R1.ChunkSection;
import net.minecraft.server.v1_14_R1.Entity;
import net.minecraft.server.v1_14_R1.EntityPlayer;
import net.minecraft.server.v1_14_R1.EntityTypes;
import net.minecraft.server.v1_14_R1.IBlockData;
import net.minecraft.server.v1_14_R1.IRegistry;
import net.minecraft.server.v1_14_R1.ItemStack;
import net.minecraft.server.v1_14_R1.MinecraftKey;
import net.minecraft.server.v1_14_R1.NBTBase;
import net.minecraft.server.v1_14_R1.NBTTagCompound;
import net.minecraft.server.v1_14_R1.NBTTagInt;
import net.minecraft.server.v1_14_R1.PacketPlayOutMapChunk;
import net.minecraft.server.v1_14_R1.PlayerChunk;
import net.minecraft.server.v1_14_R1.TileEntity;
import net.minecraft.server.v1_14_R1.World;
import net.minecraft.server.v1_14_R1.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_14_R1.CraftChunk;
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_14_R1.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.util.Map;
import java.util.OptionalInt;
import java.util.function.Supplier;
import java.util.stream.Stream;
import static com.google.common.base.Preconditions.checkNotNull;
public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> {
private final BukkitImplAdapter<NBTBase> parent;
// ------------------------------------------------------------------------
// Code that may break between versions of Minecraft
// ------------------------------------------------------------------------
public FAWE_Spigot_v1_14_R4() throws NoSuchFieldException, NoSuchMethodException {
this.parent = new Spigot_v1_14_R4();
}
@Override
public BukkitImplAdapter<NBTBase> getParent() {
return parent;
}
public char[] idbToStateOrdinal;
private synchronized boolean init() {
if (idbToStateOrdinal != null) return false;
idbToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size
for (int i = 0; i < idbToStateOrdinal.length; i++) {
BlockState state = BlockTypesCache.states[i];
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
int id = Block.REGISTRY_ID.getId(material.getState());
idbToStateOrdinal[id] = state.getOrdinalChar();
}
return true;
}
@Override
public BlockMaterial getMaterial(BlockType blockType) {
return new BlockMaterial_1_14(getBlock(blockType));
}
@Override
public BlockMaterial getMaterial(BlockState state) {
IBlockData bs = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState();
return new BlockMaterial_1_14(bs.getBlock(), bs);
}
public Block getBlock(BlockType blockType) {
return IRegistry.BLOCK.get(new MinecraftKey(blockType.getNamespace(), blockType.getResource()));
}
@SuppressWarnings("deprecation")
@Override
public BaseBlock getBlock(Location location) {
checkNotNull(location);
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
org.bukkit.block.Block bukkitBlock = location.getBlock();
BlockState state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
if (state.getBlockType().getMaterial().hasContainer()) {
//Read the NBT data
TileEntity te = craftWorld.getHandle().getTileEntity(new BlockPosition(x, y, z));
if (te != null) {
NBTTagCompound tag = new NBTTagCompound();
te.save(tag); // readTileEntityIntoTag
return state.toBaseBlock((CompoundTag) toNative(tag));
}
}
return state.toBaseBlock();
}
@Override
public boolean setBlock(Location location, BlockStateHolder state, boolean notifyAndLight) {
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, notifyAndLight);
}
public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) {
CraftChunk craftChunk = (CraftChunk) chunk;
Chunk nmsChunk = craftChunk.getHandle();
World nmsWorld = nmsChunk.getWorld();
IBlockData blockData = ((BlockMaterial_1_14) state.getMaterial()).getState();
ChunkSection[] sections = nmsChunk.getSections();
int y4 = y >> 4;
ChunkSection section = sections[y4];
IBlockData existing;
if (section == null) {
existing = ((BlockMaterial_1_14) BlockTypes.AIR.getDefaultState().getMaterial()).getState();
} else {
existing = section.getType(x & 15, y & 15, z & 15);
}
BlockPosition pos = new BlockPosition(x, y, z);
nmsChunk.removeTileEntity(pos); // Force delete the old tile entity
CompoundTag nativeTag = state instanceof BaseBlock ? ((BaseBlock)state).getNbtData() : null;
if (nativeTag != null || existing instanceof TileEntityBlock) {
nmsWorld.setTypeAndData(pos, blockData, 0);
// remove tile
if (nativeTag != null) {
// We will assume that the tile entity was created for us,
// though we do not do this on the Forge version
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
if (tileEntity != null) {
NBTTagCompound tag = (NBTTagCompound) fromNative(nativeTag);
tag.set("x", new NBTTagInt(x));
tag.set("y", new NBTTagInt(y));
tag.set("z", new NBTTagInt(z));
tileEntity.load(tag); // readTagIntoTileEntity
}
}
} else {
if (existing == blockData) return true;
if (section == null) {
if (blockData.isAir()) return true;
sections[y4] = section = new ChunkSection(y4 << 4);
}
nmsChunk.setType(pos = new BlockPosition(x, y, z), blockData, false);
}
if (update) {
nmsWorld.getMinecraftWorld().notify(pos, existing, blockData, 0);
}
return true;
}
@Nullable
private static String getEntityId(Entity entity) {
MinecraftKey minecraftkey = EntityTypes.getName(entity.getEntityType());
return minecraftkey == null ? null : minecraftkey.toString();
}
private static void readEntityIntoTag(Entity entity, NBTTagCompound tag) {
entity.save(tag);
}
@Override
public BaseEntity getEntity(org.bukkit.entity.Entity entity) {
checkNotNull(entity);
CraftEntity craftEntity = ((CraftEntity) entity);
Entity mcEntity = craftEntity.getHandle();
String id = getEntityId(mcEntity);
if (id != null) {
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
Supplier<CompoundTag> saveTag = () -> {
NBTTagCompound tag = new NBTTagCompound();
readEntityIntoTag(mcEntity, tag);
return (CompoundTag) toNative(tag);
};
return new LazyBaseEntity(type, saveTag);
} else {
return null;
}
}
@Override
public OptionalInt getInternalBlockStateId(BlockState state) {
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
if (material.isAir()) {
return OptionalInt.empty();
}
IBlockData mcState = material.getCraftBlockData().getState();
return OptionalInt.of(Block.REGISTRY_ID.getId(mcState));
}
@Override
public BlockState adapt(BlockData blockData) {
CraftBlockData cbd = ((CraftBlockData) blockData);
IBlockData ibd = cbd.getState();
return adapt(ibd);
}
public BlockState adapt(IBlockData ibd) {
return BlockTypesCache.states[adaptToInt(ibd)];
}
public int adaptToInt(IBlockData ibd) {
try {
int id = Block.REGISTRY_ID.getId(ibd);
return idbToStateOrdinal[id];
} catch (NullPointerException e) {
init();
return adaptToInt(ibd);
}
}
public char adaptToChar(IBlockData ibd) {
try {
int id = Block.REGISTRY_ID.getId(ibd);
return idbToStateOrdinal[id];
} catch (NullPointerException e) {
init();
return adaptToChar(ibd);
}
}
@Override
public BlockData adapt(BlockStateHolder state) {
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
return material.getCraftBlockData();
}
@Override
public void notifyAndLightBlock(Location position, BlockState previousType) {
this.setBlock(position.getChunk(), position.getBlockX(), position.getBlockY(), position.getBlockZ(), previousType, true);
}
private MapChunkUtil_1_14 mapUtil = new MapChunkUtil_1_14();
@Override
public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket packet) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
PlayerChunk map = BukkitAdapter_1_14.getPlayerChunk(nmsWorld, packet.getChunkX(), packet.getChunkZ());
if (map != null && map.hasBeenLoaded()) {
boolean flag = false;
PlayerChunk.d players = map.players;
Stream<EntityPlayer> stream = players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag);
EntityPlayer checkPlayer = player == null ? null : ((CraftPlayer) player).getHandle();
stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer)
.forEach(entityPlayer -> {
synchronized (packet) {
PacketPlayOutMapChunk nmsPacket = (PacketPlayOutMapChunk) packet.getNativePacket();
if (nmsPacket == null) {
nmsPacket = mapUtil.create( this, packet);
packet.setNativePacket(nmsPacket);
}
try {
FaweCache.IMP.CHUNK_FLAG.get().set(true);
entityPlayer.playerConnection.sendPacket(nmsPacket);
} finally {
FaweCache.IMP.CHUNK_FLAG.get().set(false);
}
}
});
}
}
@Override
public Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
Map<String, ? extends Property<?>> result = getParent().getProperties(blockType);
System.out.println("Result " + result);
return result;
}
@Override
public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) {
ItemStack stack = new ItemStack(IRegistry.ITEM.get(MinecraftKey.a(item.getType().getId())), item.getAmount());
stack.setTag(((NBTTagCompound) fromNative(item.getNbtData())));
return CraftItemStack.asCraftMirror(stack);
}
@Override
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount());
weStack.setNbtData(((CompoundTag) toNative(nmsStack.getTag())));
return weStack;
}
}

View File

@ -1,80 +0,0 @@
package com.boydti.fawe.bukkit.adapter.mc1_14;
import com.mojang.authlib.GameProfile;
import net.minecraft.server.v1_14_R1.DamageSource;
import net.minecraft.server.v1_14_R1.DimensionManager;
import net.minecraft.server.v1_14_R1.Entity;
import net.minecraft.server.v1_14_R1.EntityPlayer;
import net.minecraft.server.v1_14_R1.IChatBaseComponent;
import net.minecraft.server.v1_14_R1.ITileInventory;
import net.minecraft.server.v1_14_R1.PacketPlayInSettings;
import net.minecraft.server.v1_14_R1.PlayerInteractManager;
import net.minecraft.server.v1_14_R1.Statistic;
import net.minecraft.server.v1_14_R1.Vec3D;
import net.minecraft.server.v1_14_R1.WorldServer;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import javax.annotation.Nullable;
import java.util.OptionalInt;
import java.util.UUID;
class FakePlayer_v1_14_R4 extends EntityPlayer {
private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]");
FakePlayer_v1_14_R4(WorldServer world) {
super(world.getMinecraftServer(), world, FAKE_WORLDEDIT_PROFILE, new PlayerInteractManager(world));
}
@Override
public Vec3D bP() {
return new Vec3D(0, 0, 0);
}
@Override
public void tick() {
}
@Override
public void die(DamageSource damagesource) {
}
@Override
public Entity a(DimensionManager dimensionmanager, TeleportCause cause) {
return this;
}
@Override
public OptionalInt openContainer(@Nullable ITileInventory itileinventory) {
return OptionalInt.empty();
}
@Override
public void a(PacketPlayInSettings packetplayinsettings) {
}
@Override
public void sendMessage(IChatBaseComponent ichatbasecomponent) {
}
@Override
public void a(IChatBaseComponent ichatbasecomponent, boolean flag) {
}
@Override
public void a(Statistic<?> statistic, int i) {
}
@Override
public void a(Statistic<?> statistic) {
}
@Override
public boolean isInvulnerable(DamageSource damagesource) {
return true;
}
@Override
public boolean p(boolean flag) { // canEat, search for foodData usage
return true;
}
}

View File

@ -1,129 +1,28 @@
package com.boydti.fawe.bukkit.adapter.mc1_14;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.IBlocks;
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
import com.boydti.fawe.object.FaweInputStream;
import com.boydti.fawe.object.FaweOutputStream;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.NBTInputStream;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType;
import net.minecraft.server.v1_14_R1.Chunk;
import net.minecraft.server.v1_14_R1.ChunkSection;
import net.minecraft.server.v1_14_R1.IRegistry;
import net.minecraft.server.v1_14_R1.NBTBase;
import net.minecraft.server.v1_14_R1.NBTTagCompound;
import com.boydti.fawe.bukkit.adapter.MapChunkUtil;
import net.minecraft.server.v1_14_R1.PacketPlayOutMapChunk;
import net.minecraft.server.v1_14_R1.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.function.Supplier;
public class MapChunkUtil_1_14 {
private static final Field fieldX;
private static final Field fieldZ;
private static final Field fieldHeightMap;
private static final Field fieldBitMask;
private static final Field fieldChunkData;
private static final Field fieldBlockEntities;
private static final Field fieldFull;
static {
try {
fieldX = PacketPlayOutMapChunk.class.getDeclaredField("a");
fieldZ = PacketPlayOutMapChunk.class.getDeclaredField("b");
fieldBitMask = PacketPlayOutMapChunk.class.getDeclaredField("c");
fieldHeightMap = PacketPlayOutMapChunk.class.getDeclaredField("d");
fieldChunkData = PacketPlayOutMapChunk.class.getDeclaredField("e");
fieldBlockEntities = PacketPlayOutMapChunk.class.getDeclaredField("f");
fieldFull = PacketPlayOutMapChunk.class.getDeclaredField("g");
fieldX.setAccessible(true);
fieldZ.setAccessible(true);
fieldBitMask.setAccessible(true);
fieldHeightMap.setAccessible(true);
fieldChunkData.setAccessible(true);
fieldBlockEntities.setAccessible(true);
fieldFull.setAccessible(true);
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e);
}
public class MapChunkUtil_1_14 extends MapChunkUtil<PacketPlayOutMapChunk> {
public MapChunkUtil_1_14() throws NoSuchFieldException {
fieldX = PacketPlayOutMapChunk.class.getDeclaredField("a");
fieldZ = PacketPlayOutMapChunk.class.getDeclaredField("b");
fieldBitMask = PacketPlayOutMapChunk.class.getDeclaredField("c");
fieldHeightMap = PacketPlayOutMapChunk.class.getDeclaredField("d");
fieldChunkData = PacketPlayOutMapChunk.class.getDeclaredField("e");
fieldBlockEntities = PacketPlayOutMapChunk.class.getDeclaredField("f");
fieldFull = PacketPlayOutMapChunk.class.getDeclaredField("g");
fieldX.setAccessible(true);
fieldZ.setAccessible(true);
fieldBitMask.setAccessible(true);
fieldHeightMap.setAccessible(true);
fieldChunkData.setAccessible(true);
fieldBlockEntities.setAccessible(true);
fieldFull.setAccessible(true);
}
public static PacketPlayOutMapChunk create(WorldServer world, BukkitImplAdapter<NBTBase> adapter, ChunkPacket packet) {
IBlocks chunk = packet.getChunk();
try {
PacketPlayOutMapChunk nmsPacket;
int bitMask = packet.getChunk().getBitMask();
if (bitMask == 0) { // TODO remove once sending tiles/entities is fixed
nmsPacket = Fawe.get().getQueueHandler().sync((Callable<PacketPlayOutMapChunk>) () -> {
Chunk nmsChunk = world.getChunkAt(packet.getChunkX(), packet.getChunkZ());
PacketPlayOutMapChunk nmsPacket1 = new PacketPlayOutMapChunk(nmsChunk, 65535);
byte[] data = (byte[]) fieldChunkData.get(nmsPacket1);
int len = data.length;
ByteBuffer buffer = ByteBuffer.wrap(data, len - 256 * 4, 256 * 4);
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
BiomeType biome = chunk.getBiomeType(x, z);
if (biome != null) {
buffer.putInt(biome.getLegacyId());
} else {
buffer.getInt();
}
}
}
return nmsPacket1;
}).get();
} else {
nmsPacket = new PacketPlayOutMapChunk();
fieldX.setInt(nmsPacket, packet.getChunkX());
fieldZ.setInt(nmsPacket, packet.getChunkZ());
fieldBitMask.set(nmsPacket, packet.getChunk().getBitMask());
NBTBase heightMap = adapter.fromNative(/* packet.getHeightMap() */ new CompoundTag(new HashMap<>()));
fieldHeightMap.set(nmsPacket, heightMap);
fieldChunkData.set(nmsPacket, packet.getSectionBytes());
Map<BlockVector3, CompoundTag> tiles = packet.getChunk().getTiles();
ArrayList<NBTTagCompound> nmsTiles = new ArrayList<>(tiles.size());
for (Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
NBTBase nmsTag = adapter.fromNative(entry.getValue());
nmsTiles.add((NBTTagCompound) nmsTag);
}
fieldBlockEntities.set(nmsPacket, nmsTiles);
fieldFull.set(nmsPacket, packet.isFull());
}
return nmsPacket;
} catch (Exception e) {
e.printStackTrace();
return null;
}
@Override
public PacketPlayOutMapChunk createPacket() {
return new PacketPlayOutMapChunk();
}
}

View File

@ -1,757 +0,0 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.boydti.fawe.bukkit.adapter.mc1_14;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.sk89q.jnbt.ByteArrayTag;
import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.DoubleTag;
import com.sk89q.jnbt.EndTag;
import com.sk89q.jnbt.FloatTag;
import com.sk89q.jnbt.IntArrayTag;
import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.LongArrayTag;
import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.NBTConstants;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.TileEntityBlock;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.CachedBukkitAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.LazyBaseEntity;
import com.sk89q.worldedit.internal.Constants;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.BooleanProperty;
import com.sk89q.worldedit.registry.state.DirectionalProperty;
import com.sk89q.worldedit.registry.state.EnumProperty;
import com.sk89q.worldedit.registry.state.IntegerProperty;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.DataFixer;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.OptionalInt;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import net.minecraft.server.v1_14_R1.Block;
import net.minecraft.server.v1_14_R1.BlockPosition;
import net.minecraft.server.v1_14_R1.BlockStateBoolean;
import net.minecraft.server.v1_14_R1.BlockStateDirection;
import net.minecraft.server.v1_14_R1.BlockStateEnum;
import net.minecraft.server.v1_14_R1.BlockStateInteger;
import net.minecraft.server.v1_14_R1.BlockStateList;
import net.minecraft.server.v1_14_R1.Chunk;
import net.minecraft.server.v1_14_R1.ChunkCoordIntPair;
import net.minecraft.server.v1_14_R1.ChunkSection;
import net.minecraft.server.v1_14_R1.Entity;
import net.minecraft.server.v1_14_R1.EntityPlayer;
import net.minecraft.server.v1_14_R1.EntityTypes;
import net.minecraft.server.v1_14_R1.EnumDirection;
import net.minecraft.server.v1_14_R1.EnumHand;
import net.minecraft.server.v1_14_R1.EnumInteractionResult;
import net.minecraft.server.v1_14_R1.IBlockData;
import net.minecraft.server.v1_14_R1.IBlockState;
import net.minecraft.server.v1_14_R1.INamable;
import net.minecraft.server.v1_14_R1.IRegistry;
import net.minecraft.server.v1_14_R1.ItemActionContext;
import net.minecraft.server.v1_14_R1.ItemStack;
import net.minecraft.server.v1_14_R1.MinecraftKey;
import net.minecraft.server.v1_14_R1.MovingObjectPositionBlock;
import net.minecraft.server.v1_14_R1.NBTBase;
import net.minecraft.server.v1_14_R1.NBTTagByte;
import net.minecraft.server.v1_14_R1.NBTTagByteArray;
import net.minecraft.server.v1_14_R1.NBTTagCompound;
import net.minecraft.server.v1_14_R1.NBTTagDouble;
import net.minecraft.server.v1_14_R1.NBTTagEnd;
import net.minecraft.server.v1_14_R1.NBTTagFloat;
import net.minecraft.server.v1_14_R1.NBTTagInt;
import net.minecraft.server.v1_14_R1.NBTTagIntArray;
import net.minecraft.server.v1_14_R1.NBTTagList;
import net.minecraft.server.v1_14_R1.NBTTagLong;
import net.minecraft.server.v1_14_R1.NBTTagLongArray;
import net.minecraft.server.v1_14_R1.NBTTagShort;
import net.minecraft.server.v1_14_R1.NBTTagString;
import net.minecraft.server.v1_14_R1.PacketPlayOutEntityStatus;
import net.minecraft.server.v1_14_R1.PacketPlayOutMapChunk;
import net.minecraft.server.v1_14_R1.PacketPlayOutTileEntityData;
import net.minecraft.server.v1_14_R1.PlayerChunk;
import net.minecraft.server.v1_14_R1.PlayerChunkMap;
import net.minecraft.server.v1_14_R1.TileEntity;
import net.minecraft.server.v1_14_R1.Vec3D;
import net.minecraft.server.v1_14_R1.World;
import net.minecraft.server.v1_14_R1.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_14_R1.CraftChunk;
import org.bukkit.craftbukkit.v1_14_R1.CraftServer;
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_14_R1.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_14_R1.util.CraftMagicNumbers;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class Spigot_v1_14_R4 extends CachedBukkitAdapter implements BukkitImplAdapter<NBTBase>{
private final Logger logger = LoggerFactory.getLogger(getClass());
private final Field nbtListTagListField;
private final Method nbtCreateTagMethod;
static {
// A simple test
if (!Bukkit.getServer().getClass().getName().endsWith("DummyServer")) CraftServer.class.cast(Bukkit.getServer());
}
// ------------------------------------------------------------------------
// Code that may break between versions of Minecraft
// ------------------------------------------------------------------------
public Spigot_v1_14_R4() throws NoSuchFieldException, NoSuchMethodException {
// The list of tags on an NBTTagList
nbtListTagListField = NBTTagList.class.getDeclaredField("list");
nbtListTagListField.setAccessible(true);
// The method to create an NBTBase tag given its type ID
nbtCreateTagMethod = NBTBase.class.getDeclaredMethod("createTag", byte.class);
nbtCreateTagMethod.setAccessible(true);
}
public char[] idbToStateOrdinal;
private synchronized boolean init() {
if (idbToStateOrdinal != null) return false;
idbToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size
for (int i = 0; i < idbToStateOrdinal.length; i++) {
BlockState state = BlockTypesCache.states[i];
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
int id = Block.REGISTRY_ID.getId(material.getState());
idbToStateOrdinal[id] = state.getOrdinalChar();
}
return true;
}
/**
* Read the given NBT data into the given tile entity.
*
* @param tileEntity the tile entity
* @param tag the tag
*/
private static void readTagIntoTileEntity(NBTTagCompound tag, TileEntity tileEntity) {
try {
tileEntity.load(tag);
} catch (Throwable e) {
//Fawe.debug("Invalid tag " + tag + " | " + tileEntity);
}
}
/**
* Write the tile entity's NBT data to the given tag.
*
* @param tileEntity the tile entity
* @param tag the tag
*/
private static void readTileEntityIntoTag(TileEntity tileEntity, NBTTagCompound tag) {
tileEntity.save(tag);
}
/**
* Get the ID string of the given entity.
*
* @param entity the entity
* @return the entity ID or null if one is not known
*/
@Nullable
private static String getEntityId(Entity entity) {
MinecraftKey minecraftkey = EntityTypes.getName(entity.getBukkitEntity().getHandle().getEntityType());
return minecraftkey == null ? null : minecraftkey.toString();
}
/**
* Create an entity using the given entity ID.
*
* @param id the entity ID
* @param world the world
* @return an entity or null
*/
@Nullable
private static Entity createEntityFromId(String id, World world) {
return EntityTypes.a(id).get().a(world);
}
/**
* Write the given NBT data into the given entity.
*
* @param entity the entity
* @param tag the tag
*/
private static void readTagIntoEntity(NBTTagCompound tag, Entity entity) {
entity.f(tag);
}
/**
* Write the entity's NBT data to the given tag.
*
* @param entity the entity
* @param tag the tag
*/
private static void readEntityIntoTag(Entity entity, NBTTagCompound tag) {
entity.save(tag);
}
@Override
public BlockMaterial getMaterial(BlockType blockType) {
return new BlockMaterial_1_14(getBlock(blockType));
}
@Override
public BlockMaterial getMaterial(BlockState state) {
IBlockData bs = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState();
return new BlockMaterial_1_14(bs.getBlock(), bs);
}
public Block getBlock(BlockType blockType) {
return IRegistry.BLOCK.get(new MinecraftKey(blockType.getNamespace(), blockType.getResource()));
}
// ------------------------------------------------------------------------
// Code that is less likely to break
// ------------------------------------------------------------------------
@Override
public int getDataVersion() {
return CraftMagicNumbers.INSTANCE.getDataVersion();
}
@Override
public DataFixer getDataFixer() {
return DataConverters_1_14_R4.INSTANCE;
}
@SuppressWarnings("deprecation")
@Override
public BaseBlock getBlock(Location location) {
checkNotNull(location);
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
org.bukkit.block.Block bukkitBlock = location.getBlock();
BlockState state = BukkitAdapter.adapt(bukkitBlock.getBlockData());
if (state.getBlockType().getMaterial().hasContainer()) {
//Read the NBT data
TileEntity te = craftWorld.getHandle().getTileEntity(new BlockPosition(x, y, z));
if (te != null) {
NBTTagCompound tag = new NBTTagCompound();
readTileEntityIntoTag(te, tag); // Load data
return state.toBaseBlock((CompoundTag) toNative(tag));
}
}
return state.toBaseBlock();
}
@Override
public boolean isChunkInUse(org.bukkit.Chunk chunk) {
CraftChunk craftChunk = (CraftChunk) chunk;
PlayerChunkMap chunkMap = ((WorldServer) craftChunk.getHandle().getWorld()).getChunkProvider().playerChunkMap;
return chunkMap.visibleChunks.containsKey(ChunkCoordIntPair.pair(chunk.getX(), chunk.getZ()));
}
@Override
public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) {
CraftChunk craftChunk = (CraftChunk) chunk;
Chunk nmsChunk = craftChunk.getHandle();
World nmsWorld = nmsChunk.getWorld();
IBlockData blockData = ((BlockMaterial_1_14) state.getMaterial()).getState();
ChunkSection[] sections = nmsChunk.getSections();
int y4 = y >> 4;
ChunkSection section = sections[y4];
IBlockData existing;
if (section == null) {
existing = ((BlockMaterial_1_14) BlockTypes.AIR.getDefaultState().getMaterial()).getState();
} else {
existing = section.getType(x & 15, y & 15, z & 15);
}
BlockPosition pos = new BlockPosition(x, y, z);
nmsChunk.removeTileEntity(pos); // Force delete the old tile entity
CompoundTag nativeTag = state instanceof BaseBlock ? ((BaseBlock)state).getNbtData() : null;
if (nativeTag != null || existing instanceof TileEntityBlock) {
nmsWorld.setTypeAndData(pos, blockData, 0);
// remove tile
if (nativeTag != null) {
// We will assume that the tile entity was created for us,
// though we do not do this on the Forge version
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
if (tileEntity != null) {
NBTTagCompound tag = (NBTTagCompound) fromNative(nativeTag);
tag.set("x", new NBTTagInt(x));
tag.set("y", new NBTTagInt(y));
tag.set("z", new NBTTagInt(z));
readTagIntoTileEntity(tag, tileEntity); // Load data
}
}
} else {
if (existing == blockData) return true;
if (section == null) {
if (blockData.isAir()) return true;
sections[y4] = section = new ChunkSection(y4 << 4);
}
nmsChunk.setType(pos = new BlockPosition(x, y, z), blockData, false);
}
if (update) {
nmsWorld.getMinecraftWorld().notify(pos, existing, blockData, 0);
}
return true;
}
@Override
public BaseEntity getEntity(org.bukkit.entity.Entity entity) {
checkNotNull(entity);
CraftEntity craftEntity = ((CraftEntity) entity);
Entity mcEntity = craftEntity.getHandle();
String id = getEntityId(mcEntity);
if (id != null) {
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
Supplier<CompoundTag> saveTag = new Supplier<CompoundTag>() {
@Override
public CompoundTag get() {
NBTTagCompound tag = new NBTTagCompound();
readEntityIntoTag(mcEntity, tag);
return (CompoundTag) toNative(tag);
}
};
return new LazyBaseEntity(type, saveTag);
} else {
return null;
}
}
@Nullable
@Override
public org.bukkit.entity.Entity createEntity(Location location, BaseEntity state) {
checkNotNull(location);
checkNotNull(state);
if (state.getType() == com.sk89q.worldedit.world.entity.EntityTypes.PLAYER) return null;
CraftWorld craftWorld = ((CraftWorld) location.getWorld());
WorldServer worldServer = craftWorld.getHandle();
Entity createdEntity = createEntityFromId(state.getType().getId(), craftWorld.getHandle());
if (createdEntity != null) {
CompoundTag nativeTag = state.getNbtData();
if (nativeTag != null) {
NBTTagCompound tag = (NBTTagCompound) fromNative(nativeTag);
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
tag.remove(name);
}
readTagIntoEntity(tag, createdEntity);
}
createdEntity.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
worldServer.addEntity(createdEntity, SpawnReason.CUSTOM);
return createdEntity.getBukkitEntity();
} else {
logger.debug("Invalid entity " + state.getType().getId());
return null;
}
}
@SuppressWarnings("unchecked")
@Override
public Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
Block block;
try {
block = IRegistry.BLOCK.get(new MinecraftKey(blockType.getNamespace(), blockType.getResource()));
} catch (Throwable e) {
e.printStackTrace();
return Collections.emptyMap();
}
if (block == null) {
logger.warn("Failed to find properties for " + blockType.getId());
return Collections.emptyMap();
}
Map<String, Property<?>> properties = Maps.newLinkedHashMap();
BlockStateList<Block, IBlockData> blockStateList = block.getStates();
for (IBlockState state : blockStateList.d()) {
Property property;
if (state instanceof BlockStateBoolean) {
property = new BooleanProperty(state.a(), ImmutableList.copyOf(state.getValues()));
} else if (state instanceof BlockStateDirection) {
property = new DirectionalProperty(state.a(),
(List<Direction>) state.getValues().stream().map(e -> Direction.valueOf(((INamable) e).getName().toUpperCase())).collect(Collectors.toList()));
} else if (state instanceof BlockStateEnum) {
property = new EnumProperty(state.a(),
(List<String>) state.getValues().stream().map(e -> ((INamable) e).getName()).collect(Collectors.toList()));
} else if (state instanceof BlockStateInteger) {
property = new IntegerProperty(state.a(), ImmutableList.copyOf(state.getValues()));
} else {
throw new IllegalArgumentException("WorldEdit needs an update to support " + state.getClass().getSimpleName());
}
properties.put(property.getName(), property);
}
return properties;
}
/**
* Converts from a non-native NMS NBT structure to a native WorldEdit NBT
* structure.
*
* @param foreign non-native NMS NBT structure
* @return native WorldEdit NBT structure
*/
@SuppressWarnings("unchecked")
@Override
public Tag toNative(NBTBase foreign) {
if (foreign == null) {
return null;
}
if (foreign instanceof NBTTagCompound) {
Map<String, Tag> values = new HashMap<>();
Set<String> foreignKeys = ((NBTTagCompound) foreign).getKeys(); // map.keySet
for (String str : foreignKeys) {
NBTBase base = ((NBTTagCompound) foreign).get(str);
values.put(str, toNative(base));
}
return new CompoundTag(values);
} else if (foreign instanceof NBTTagByte) {
return new ByteTag(((NBTTagByte) foreign).asByte());
} else if (foreign instanceof NBTTagByteArray) {
return new ByteArrayTag(((NBTTagByteArray) foreign).getBytes()); // data
} else if (foreign instanceof NBTTagDouble) {
return new DoubleTag(((NBTTagDouble) foreign).asDouble()); // getDouble
} else if (foreign instanceof NBTTagFloat) {
return new FloatTag(((NBTTagFloat) foreign).asFloat());
} else if (foreign instanceof NBTTagInt) {
return new IntTag(((NBTTagInt) foreign).asInt());
} else if (foreign instanceof NBTTagIntArray) {
return new IntArrayTag(((NBTTagIntArray) foreign).getInts()); // data
} else if (foreign instanceof NBTTagLongArray) {
return new LongArrayTag(((NBTTagLongArray) foreign).getLongs()); // data
} else if (foreign instanceof NBTTagList) {
try {
return toNativeList((NBTTagList) foreign);
} catch (Throwable e) {
logger.warn("Failed to convert NBTTagList", e);
return new ListTag(ByteTag.class, new ArrayList<ByteTag>());
}
} else if (foreign instanceof NBTTagLong) {
return new LongTag(((NBTTagLong) foreign).asLong());
} else if (foreign instanceof NBTTagShort) {
return new ShortTag(((NBTTagShort) foreign).asShort());
} else if (foreign instanceof NBTTagString) {
return new StringTag(foreign.asString());
} else if (foreign instanceof NBTTagEnd) {
return new EndTag();
} else {
throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName());
}
}
/**
* Convert a foreign NBT list tag into a native WorldEdit one.
*
* @param foreign the foreign tag
* @return the converted tag
* @throws NoSuchFieldException on error
* @throws SecurityException on error
* @throws IllegalArgumentException on error
* @throws IllegalAccessException on error
*/
public ListTag toNativeList(NBTTagList foreign) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
List<Tag> values = new ArrayList<>();
int type = foreign.getTypeId();
List foreignList;
foreignList = (List) nbtListTagListField.get(foreign);
for (int i = 0; i < foreign.size(); i++) {
NBTBase element = (NBTBase) foreignList.get(i);
values.add(toNative(element)); // List elements shouldn't have names
}
Class<? extends Tag> cls = NBTConstants.getClassFromType(type);
return new ListTag(cls, values);
}
/**
* Converts a WorldEdit-native NBT structure to a NMS structure.
*
* @param foreign structure to convert
* @return non-native structure
*/
@Override
public NBTBase fromNative(Tag foreign) {
if (foreign == null) {
return null;
}
if (foreign instanceof CompoundTag) {
NBTTagCompound tag = new NBTTagCompound();
for (Map.Entry<String, Tag> entry : ((CompoundTag) foreign)
.getValue().entrySet()) {
tag.set(entry.getKey(), fromNative(entry.getValue()));
}
return tag;
} else if (foreign instanceof ByteTag) {
return new NBTTagByte(((ByteTag) foreign).getValue());
} else if (foreign instanceof ByteArrayTag) {
return new NBTTagByteArray(((ByteArrayTag) foreign).getValue());
} else if (foreign instanceof DoubleTag) {
return new NBTTagDouble(((DoubleTag) foreign).getValue());
} else if (foreign instanceof FloatTag) {
return new NBTTagFloat(((FloatTag) foreign).getValue());
} else if (foreign instanceof IntTag) {
return new NBTTagInt(((IntTag) foreign).getValue());
} else if (foreign instanceof IntArrayTag) {
return new NBTTagIntArray(((IntArrayTag) foreign).getValue());
} else if (foreign instanceof LongArrayTag) {
return new NBTTagLongArray(((LongArrayTag) foreign).getValue());
} else if (foreign instanceof ListTag) {
NBTTagList tag = new NBTTagList();
ListTag foreignList = (ListTag) foreign;
for (Tag t : foreignList.getValue()) {
tag.add(fromNative(t));
}
return tag;
} else if (foreign instanceof LongTag) {
return new NBTTagLong(((LongTag) foreign).getValue());
} else if (foreign instanceof ShortTag) {
return new NBTTagShort(((ShortTag) foreign).getValue());
} else if (foreign instanceof StringTag) {
return new NBTTagString(((StringTag) foreign).getValue());
} else if (foreign instanceof EndTag) {
try {
return (NBTBase) nbtCreateTagMethod.invoke(null, (byte) 0);
} catch (Exception e) {
return null;
}
} else {
throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName());
}
}
@Override
public OptionalInt getInternalBlockStateId(BlockState state) {
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
IBlockData mcState = material.getCraftBlockData().getState();
return OptionalInt.of(Block.REGISTRY_ID.getId(mcState));
}
@Override
public BlockState adapt(BlockData blockData) {
CraftBlockData cbd = ((CraftBlockData) blockData);
IBlockData ibd = cbd.getState();
return adapt(ibd);
}
public BlockState adapt(IBlockData ibd) {
return BlockTypesCache.states[adaptToInt(ibd)];
}
public int adaptToInt(IBlockData ibd) {
try {
int id = Block.REGISTRY_ID.getId(ibd);
return idbToStateOrdinal[id];
} catch (NullPointerException e) {
init();
return adaptToInt(ibd);
}
}
public char adaptToChar(IBlockData ibd) {
try {
int id = Block.REGISTRY_ID.getId(ibd);
return idbToStateOrdinal[id];
} catch (NullPointerException e) {
init();
return adaptToChar(ibd);
}
}
@Override
public BlockData adapt(BlockStateHolder state) {
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
return material.getCraftBlockData();
}
@Override
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundTag nbtData) {
((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutTileEntityData(
new BlockPosition(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()),
7,
(NBTTagCompound) fromNative(nbtData)
));
}
@Override
public void notifyAndLightBlock(Location position, BlockState previousType) {
this.setBlock(position.getChunk(), position.getBlockX(), position.getBlockY(), position.getBlockZ(), previousType, true);
}
@Override
public void sendFakeOP(Player player) {
((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutEntityStatus(
((CraftPlayer) player).getHandle(), (byte) 28
));
}
@Override
public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket packet) {
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
PlayerChunk map = BukkitAdapter_1_14.getPlayerChunk(nmsWorld, packet.getChunkX(), packet.getChunkZ());
if (map != null && map.hasBeenLoaded()) {
boolean flag = false;
PlayerChunk.d players = map.players;
Stream<EntityPlayer> stream = players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag);
EntityPlayer checkPlayer = player == null ? null : ((CraftPlayer) player).getHandle();
stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer)
.forEach(entityPlayer -> {
synchronized (packet) {
PacketPlayOutMapChunk nmsPacket = (PacketPlayOutMapChunk) packet.getNativePacket();
if (nmsPacket == null) {
nmsPacket = MapChunkUtil_1_14.create(nmsWorld, this, packet);
packet.setNativePacket(nmsPacket);
}
try {
FaweCache.IMP.CHUNK_FLAG.get().set(true);
entityPlayer.playerConnection.sendPacket(nmsPacket);
} finally {
FaweCache.IMP.CHUNK_FLAG.get().set(false);
}
}
});
}
}
private static EnumDirection adapt(Direction face) {
switch (face) {
case NORTH: return EnumDirection.NORTH;
case SOUTH: return EnumDirection.SOUTH;
case WEST: return EnumDirection.WEST;
case EAST: return EnumDirection.EAST;
case DOWN: return EnumDirection.DOWN;
case UP:
default:
return EnumDirection.UP;
}
}
private LoadingCache<WorldServer, FakePlayer_v1_14_R4> fakePlayers = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(FakePlayer_v1_14_R4::new));
@Override
public synchronized boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) {
CraftWorld craftWorld = (CraftWorld) world;
WorldServer worldServer = craftWorld.getHandle();
ItemStack stack = CraftItemStack.asNMSCopy(BukkitAdapter.adapt(item instanceof BaseItemStack
? ((BaseItemStack) item) : new BaseItemStack(item.getType(), item.getNbtData(), 1)));
stack.setTag((NBTTagCompound) fromNative(item.getNbtData()));
FakePlayer_v1_14_R4 fakePlayer;
try {
fakePlayer = fakePlayers.get(worldServer);
} catch (ExecutionException ignored) {
return false;
}
fakePlayer.a(EnumHand.MAIN_HAND, stack);
fakePlayer.setLocation(position.getBlockX(), position.getBlockY(), position.getBlockZ(),
(float) face.toVector().toYaw(), (float) face.toVector().toPitch());
final BlockPosition blockPos = new BlockPosition(position.getBlockX(), position.getBlockY(), position.getBlockZ());
final Vec3D blockVec = new Vec3D(blockPos);
final EnumDirection enumFacing = adapt(face);
MovingObjectPositionBlock rayTrace = new MovingObjectPositionBlock(blockVec, enumFacing, blockPos, false);
ItemActionContext context = new ItemActionContext(fakePlayer, EnumHand.MAIN_HAND, rayTrace);
EnumInteractionResult result = stack.placeItem(context, EnumHand.MAIN_HAND);
if (result != EnumInteractionResult.SUCCESS) {
if (worldServer.getType(blockPos).interact(worldServer, fakePlayer, EnumHand.MAIN_HAND, rayTrace)) {
result = EnumInteractionResult.SUCCESS;
} else {
result = stack.getItem().a(worldServer, fakePlayer, EnumHand.MAIN_HAND).a();
}
}
return result == EnumInteractionResult.SUCCESS;
}
@Override
public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) {
ItemStack stack = new ItemStack(IRegistry.ITEM.get(MinecraftKey.a(item.getType().getId())), item.getAmount());
stack.setTag(((NBTTagCompound) fromNative(item.getNbtData())));
return CraftItemStack.asCraftMirror(stack);
}
@Override
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount());
weStack.setNbtData(((CompoundTag) toNative(nmsStack.getTag())));
return weStack;
}
}

View File

@ -1,34 +0,0 @@
package com.boydti.fawe.bukkit.adapter.mc1_14.test;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.wrappers.WrappedBlockData;
import org.bukkit.plugin.Plugin;
import java.util.List;
public class TestChunkPacketSend {
public TestChunkPacketSend(Plugin plugin) {
// Disable all sound effects
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
protocolManager.addPacketListener(
new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.MAP_CHUNK) {
@Override
public void onPacketSending(PacketEvent event) {
if (event.getPacketType() != PacketType.Play.Server.MAP_CHUNK) {
return;
}
PacketContainer packet = event.getPacket();
StructureModifier<Byte> bytes = packet.getBytes();
StructureModifier<WrappedBlockData> blockData = packet.getBlockData();
List<WrappedBlockData> values = blockData.getValues();
}
});
}
}

View File

@ -192,7 +192,7 @@ public class AsyncBlock implements Block {
@Override
public void setType(@NotNull Material type) {
try {
world.setBlock(x, y, z, BukkitAdapter.adapt(type).getDefaultState());
world.setBlock(x, y, z, BukkitAdapter.asBlockType(type).getDefaultState());
} catch (WorldEditException e) {
throw new RuntimeException(e);
}

View File

@ -353,10 +353,6 @@ public enum BukkitAdapter {
public static BlockState adapt(@NotNull BlockData blockData) {
return getAdapter().adapt(blockData);
}
public static BlockType adapt(Material material) {
return getAdapter().adapt(material);
}
/*
private static Map<String, BlockData> blockDataCache = new HashMap<>();
*/

View File

@ -127,7 +127,7 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
}
@Override
public Collection<String> registerBlocks() {
public Collection<String> values() {
ArrayList<String> blocks = new ArrayList<>();
for (Material m : Material.values()) {
if (!m.isLegacy() && m.isBlock()) {

View File

@ -1,6 +1,22 @@
package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.world.registry.BundledItemRegistry;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import java.util.ArrayList;
import java.util.Collection;
public class BukkitItemRegistry extends BundledItemRegistry {
@Override
public Collection<String> values() {
ArrayList<String> values = new ArrayList<>();
for (Material m : Material.values()) {
if (!m.isLegacy() && (m.isBlock() || m.isItem())) {
String id = m.getKey().toString();
values.add(id);
}
}
return values;
}
}

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import com.sk89q.worldedit.world.registry.BlockCategoryRegistry;
import com.sk89q.worldedit.world.registry.BlockRegistry;
import com.sk89q.worldedit.world.registry.BundledItemRegistry;
import com.sk89q.worldedit.world.registry.BundledRegistries;
import com.sk89q.worldedit.world.registry.EntityRegistry;
import com.sk89q.worldedit.world.registry.ItemCategoryRegistry;
@ -34,6 +35,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();
private final EntityRegistry entityRegistry = new BukkitEntityRegistry();
private final BlockCategoryRegistry blockCategoryRegistry = new BukkitBlockCategoryRegistry();
@ -79,4 +81,8 @@ class BukkitRegistries extends BundledRegistries {
return INSTANCE;
}
@Override
public ItemRegistry getItemRegistry() {
return itemRegistry;
}
}

View File

@ -22,10 +22,9 @@ package com.sk89q.worldedit.bukkit;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAME;
import com.bekvon.bukkit.residence.commands.message;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.bukkit.adapter.mc1_14.Spigot_v1_14_R4;
import com.boydti.fawe.bukkit.adapter.mc1_14.FAWE_Spigot_v1_14_R4;
import com.boydti.fawe.util.MainUtil;
import com.google.common.base.Joiner;
import com.sk89q.util.yaml.YAMLProcessor;
@ -50,7 +49,6 @@ import com.sk89q.worldedit.world.block.BlockCategory;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldedit.world.item.ItemCategory;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.weather.WeatherTypes;
import io.papermc.lib.PaperLib;
import java.io.File;
@ -84,7 +82,6 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
@ -251,9 +248,8 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
String lowerCaseBiomeName = biome.name().toLowerCase(Locale.ROOT);
BiomeType.REGISTRY.register("minecraft:" + lowerCaseBiomeName, new BiomeType("minecraft:" + lowerCaseBiomeName));
}
// Block & Item
/*// Block & Item
for (Material material : Material.values()) {
/*
if (material.isBlock() && !material.isLegacy()) {
BlockType.REGISTRY.register(material.getKey().toString(), new BlockType(material.getKey().toString(), blockState -> {
// TODO Use something way less hacky than this.
@ -277,11 +273,11 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
}
}));
}
*/
if (material.isItem() && !material.isLegacy()) {
ItemType.REGISTRY.register(material.getKey().toString(), new ItemType(material.getKey().toString()));
}
}
*/
// Entity
for (org.bukkit.entity.EntityType entityType : org.bukkit.entity.EntityType.values()) {
String mcid = entityType.getName();
@ -371,7 +367,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
// Attempt to load a Bukkit adapter
BukkitImplLoader adapterLoader = new BukkitImplLoader();
try {
adapterLoader.addClass(Spigot_v1_14_R4.class);
adapterLoader.addClass(FAWE_Spigot_v1_14_R4.class);
} catch (Throwable throwable) {
throwable.printStackTrace();
}

View File

@ -26,6 +26,7 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.state.Property;
@ -36,17 +37,24 @@ 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.registry.BlockMaterial;
import java.util.Map;
import java.util.OptionalInt;
import javax.annotation.Nullable;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Map;
import java.util.OptionalInt;
import javax.annotation.Nullable;
import java.util.Map;
import java.util.OptionalInt;
import javax.annotation.Nullable;
/**
* An interface for adapters of various Bukkit implementations.
*/
@ -67,6 +75,19 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
@Nullable
DataFixer getDataFixer();
/**
* @return {@code true} if {@link #tickWatchdog()} is implemented
*/
default boolean supportsWatchdog() {
return false;
}
/**
* Tick the server watchdog, if possible.
*/
default void tickWatchdog() {
}
/**
* Get the block at the given location.
*
@ -83,11 +104,7 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
* @param notifyAndLight notify and light if set
* @return true if a block was likely changed
*/
default boolean setBlock(Location location, BlockStateHolder<?> state, boolean notifyAndLight) {
return this.setBlock(location.getChunk(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), state, notifyAndLight);
}
boolean setBlock(Chunk chunk, int x, int y, int z, BlockStateHolder<?> state, boolean update);
boolean setBlock(Location location, BlockStateHolder<?> state, boolean notifyAndLight);
/**
* Notifies the simulation that the block at the given location has
@ -142,13 +159,6 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
*/
void sendFakeOP(Player player);
/**
* Send a fake chunk packet to a player
* @param player
* @param packet
*/
void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket packet);
/**
* Simulates a player using an item.
*
@ -178,10 +188,24 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
*/
BaseItemStack adapt(ItemStack itemStack);
boolean isChunkInUse(Chunk chunk);
default OptionalInt getInternalBlockStateId(BlockData data) {
return getInternalBlockStateId(BukkitAdapter.adapt(data));
}
/**
* Retrieve the internal ID for a given state, if possible.
*
* @param state The block state
* @return the internal ID of the state
*/
default OptionalInt getInternalBlockStateId(BlockState state) {
return OptionalInt.empty();
}
// FAWE ADDITIONS
default BlockMaterial getMaterial(BlockType blockType) {
return null;
return getMaterial(blockType.getDefaultState());
}
default BlockMaterial getMaterial(BlockState blockState) {
@ -201,12 +225,11 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
}
/**
* Retrieve the internal ID for a given state, if possible.
*
* @param state The block state
* @return the internal ID of the state
* Send a fake chunk packet to a player
* @param player
* @param packet
*/
default OptionalInt getInternalBlockStateId(BlockState state) {
return OptionalInt.empty();
default void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket packet) {
throw new UnsupportedOperationException("Cannot send fake chunks");
}
}
}

View File

@ -155,6 +155,7 @@ public class BukkitImplLoader {
*/
public BukkitImplAdapter loadAdapter() throws AdapterLoadException {
for (String className : adapterCandidates) {
System.out.println("Try load " + className);
try {
Class<?> cls = Class.forName(className);
if (cls.isSynthetic()) continue;
@ -168,6 +169,7 @@ public class BukkitImplLoader {
log.warn("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.warn("Failed to load the Bukkit adapter class '" + className + "'", e);
}

View File

@ -57,11 +57,11 @@ public abstract class CachedBukkitAdapter implements IBukkitAdapter {
}
@Override
public BlockType adapt(Material material) {
public BlockType asBlockType(Material material) {
try {
return BlockTypesCache.values[blockTypes[material.ordinal()]];
} catch (NullPointerException e) {
if (init()) return adapt(material);
if (init()) return asBlockType(material);
throw e;
}
}

View File

@ -26,6 +26,8 @@ import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldedit.world.item.ItemType;
import java.util.Locale;
import com.sk89q.worldedit.world.item.ItemTypes;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Biome;
@ -208,7 +210,9 @@ public interface IBukkitAdapter {
* @param material The material
* @return The itemtype
*/
ItemType asItemType(Material material);
default ItemType asItemType(Material material) {
return ItemTypes.get(material.getKey().toString());
}
/**
* Create a WorldEdit BlockStateHolder from a Bukkit BlockData
@ -216,9 +220,10 @@ public interface IBukkitAdapter {
* @param blockData The Bukkit BlockData
* @return The WorldEdit BlockState
*/
BlockState adapt(BlockData blockData);
BlockType adapt(Material material);
default BlockState adapt(BlockData blockData) {
String id = blockData.getAsString();
return BlockState.get(id);
}
/**
* Create a Bukkit BlockData from a WorldEdit BlockStateHolder
@ -226,7 +231,9 @@ public interface IBukkitAdapter {
* @param block The WorldEdit BlockStateHolder
* @return The Bukkit BlockData
*/
BlockData adapt(BlockStateHolder block);
default BlockData adapt(BlockStateHolder block) {
return Bukkit.createBlockData(block.getAsString());
}
/**
* Create a WorldEdit BaseItemStack from a Bukkit ItemStack

View File

@ -0,0 +1,278 @@
package com.sk89q.worldedit.bukkit.adapter;
import com.boydti.fawe.beta.implementation.packet.ChunkPacket;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.BukkitPlayer;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.DataFixer;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import javax.annotation.Nullable;
import java.util.Map;
import java.util.OptionalInt;
public interface IDelegateBukkitImplAdapter<T> extends BukkitImplAdapter<T> {
BukkitImplAdapter<T> getParent();
@Override
default int getDataVersion() {
return getParent().getDataVersion();
}
@Override
@Nullable
default DataFixer getDataFixer() {
return getParent().getDataFixer();
}
@Override
default boolean supportsWatchdog() {
return getParent().supportsWatchdog();
}
@Override
default void tickWatchdog() {
getParent().tickWatchdog();
}
@Override
default BaseBlock getBlock(Location location) {
return getParent().getBlock(location);
}
default boolean setBlock(Location location, BlockStateHolder state, boolean notifyAndLight) {
return getParent().setBlock(location, state, notifyAndLight);
}
@Override
default void notifyAndLightBlock(Location position, BlockState previousType) {
getParent().notifyAndLightBlock(position, previousType);
}
@Override
@Nullable
default BaseEntity getEntity(Entity entity) {
return getParent().getEntity(entity);
}
@Override
@Nullable
default Entity createEntity(Location location, BaseEntity state) {
return getParent().createEntity(location, state);
}
@Override
default Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
return getParent().getProperties(blockType);
}
@Override
default void sendFakeNBT(Player player, BlockVector3 pos, CompoundTag nbtData) {
getParent().sendFakeNBT(player, pos, nbtData);
}
@Override
default void sendFakeOP(Player player) {
getParent().sendFakeOP(player);
}
@Override
default boolean simulateItemUse(World world, BlockVector3 position, BaseItem item, Direction face) {
return getParent().simulateItemUse(world, position, item, face);
}
@Override
default ItemStack adapt(BaseItemStack item) {
return getParent().adapt(item);
}
@Override
default BaseItemStack adapt(ItemStack itemStack) {
return getParent().adapt(itemStack);
}
@Override
default OptionalInt getInternalBlockStateId(BlockData data) {
return getParent().getInternalBlockStateId(data);
}
@Override
default OptionalInt getInternalBlockStateId(BlockState state) {
return getParent().getInternalBlockStateId(state);
}
@Override
default BlockMaterial getMaterial(BlockType blockType) {
return getParent().getMaterial(blockType);
}
@Override
default BlockMaterial getMaterial(BlockState blockState) {
return getParent().getMaterial(blockState);
}
default Tag toNative(T foreign) {
return getParent().toNative(foreign);
}
@Override
default T fromNative(Tag foreign) {
return getParent().fromNative(foreign);
}
@Override
@Nullable
default World createWorld(WorldCreator creator) {
return getParent().createWorld(creator);
}
@Override
default void sendFakeChunk(World world, Player player, ChunkPacket packet) {
getParent().sendFakeChunk(world, player, packet);
}
@Override
default BukkitWorld asBukkitWorld(com.sk89q.worldedit.world.World world) {
return getParent().asBukkitWorld(world);
}
@Override
default World adapt(com.sk89q.worldedit.world.World world) {
return getParent().adapt(world);
}
@Override
default Location adapt(World world, Vector3 position) {
return getParent().adapt(world, position);
}
@Override
default Location adapt(World world, BlockVector3 position) {
return getParent().adapt(world, position);
}
@Override
default Location adapt(World world, com.sk89q.worldedit.util.Location location) {
return getParent().adapt(world, location);
}
@Override
default Vector3 asVector(Location location) {
return getParent().asVector(location);
}
@Override
default BlockVector3 asBlockVector(Location location) {
return getParent().asBlockVector(location);
}
@Override
default com.sk89q.worldedit.entity.Entity adapt(Entity entity) {
return getParent().adapt(entity);
}
@Override
default Material adapt(ItemType itemType) {
return getParent().adapt(itemType);
}
@Override
default Material adapt(BlockType blockType) {
return getParent().adapt(blockType);
}
@Override
default EntityType adapt(com.sk89q.worldedit.world.entity.EntityType entityType) {
return getParent().adapt(entityType);
}
@Override
default BlockType asBlockType(Material material) {
return getParent().asBlockType(material);
}
@Override
default ItemType asItemType(Material material) {
return getParent().asItemType(material);
}
@Override
default BlockState adapt(BlockData blockData) {
return getParent().adapt(blockData);
}
@Override
default BlockData adapt(BlockStateHolder block) {
return getParent().adapt(block);
}
@Override
default BukkitPlayer adapt(Player player) {
return getParent().adapt(player);
}
@Override
default Player adapt(com.sk89q.worldedit.entity.Player player) {
return getParent().adapt(player);
}
@Override
default Biome adapt(BiomeType biomeType) {
return getParent().adapt(biomeType);
}
@Override
default BiomeType adapt(Biome biome) {
return getParent().adapt(biome);
}
@Override
default boolean equals(BlockType blockType, Material type) {
return getParent().equals(blockType, type);
}
@Override
default com.sk89q.worldedit.world.World adapt(World world) {
return getParent().adapt(world);
}
@Override
default GameMode adapt(org.bukkit.GameMode gameMode) {
return getParent().adapt(gameMode);
}
@Override
default com.sk89q.worldedit.world.entity.EntityType adapt(EntityType entityType) {
return getParent().adapt(entityType);
}
@Override
default BlockState asBlockState(ItemStack itemStack) {
return getParent().asBlockState(itemStack);
}
}

View File

@ -12,7 +12,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class SimpleBukkitAdapter extends CachedBukkitAdapter {
private BlockData[][] blockDataCache;
public boolean init() {
private boolean init() {
if (blockDataCache != null) return false;
this.blockDataCache = new BlockData[BlockTypes.size()][];
blockDataCache[0] = new BlockData[] {Material.AIR.createBlockData()};

View File

@ -144,6 +144,7 @@ public class SpongeSchematicReader extends NBTSchematicReader {
BlockState state = null;
try {
String palettePart = fix(entry.getKey());
System.out.println("Read " + palettePart);
state = BlockState.get(palettePart);
} catch (InputParseException e) {
e.printStackTrace();

View File

@ -179,7 +179,7 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
// Suggest property
String input = charSequence.toString();
BlockType finalType = type;
throw new SuggestInputParseException("Invalid property " + charSequence + ":" + input + " for type " + type, input, () ->
throw new SuggestInputParseException("Invalid property " + key + ":" + input + " for type " + type, input, () ->
finalType.getProperties().stream()
.map(Property::getName)
.filter(p -> StringMan.blockStateMatches(input, p))
@ -196,6 +196,7 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
case '=': {
charSequence.setSubstring(last, i);
property = (AbstractProperty) type.getPropertyMap().get(charSequence);
if (property == null) System.out.println("No prop " + charSequence + " | " + type.getPropertyMap());
last = i + 1;
break;
}

View File

@ -741,6 +741,7 @@ public final class BlockTypes {
private static Field[] fieldsTmp;
private static JoinedCharSequence joined;
private static int initIndex = 0;
public static BlockType init() {
if (fieldsTmp == null) {
fieldsTmp = BlockTypes.class.getDeclaredFields();

View File

@ -176,7 +176,7 @@ public class BlockTypesCache {
Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS);
Registries registries = platform.getRegistries();
BlockRegistry blockReg = registries.getBlockRegistry();
Collection<String> blocks = blockReg.registerBlocks();
Collection<String> blocks = blockReg.values();
Map<String, String> blockMap = blocks.stream().collect(Collectors.toMap(item -> item.charAt(item.length() - 1) == ']' ? item.substring(0, item.indexOf('[')) : item, item -> item));
int size = blockMap.size();

View File

@ -0,0 +1,22 @@
package com.sk89q.worldedit.world.block;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.ItemRegistry;
import com.sk89q.worldedit.world.registry.Registries;
public final class ItemTypesCache {
public static void init() {}
static {
Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS);
Registries registries = platform.getRegistries();
ItemRegistry itemReg = registries.getItemRegistry();
for (String key : itemReg.values()) {
ItemType item = new ItemType(key);
ItemType.REGISTRY.register(key, item);
}
}
}

View File

@ -77,7 +77,7 @@ public interface BlockRegistry {
/**
* Register all blocks
*/
default Collection<String> registerBlocks() {
default Collection<String> values() {
return Collections.emptyList();
}
}

View File

@ -22,6 +22,8 @@ package com.sk89q.worldedit.world.registry;
import com.sk89q.worldedit.world.item.ItemType;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Collections;
public interface ItemRegistry {
@ -34,4 +36,10 @@ public interface ItemRegistry {
@Nullable
String getName(ItemType itemType);
/**
* Register all items
*/
default Collection<String> values() {
return Collections.emptyList();
}
}