Update to 1.10

This commit is contained in:
Jesse Boyd 2016-06-09 17:50:19 +10:00
parent a43cef7b2d
commit 40c6e781a6
8 changed files with 1350 additions and 2 deletions

32
bukkit110/build.gradle Normal file
View File

@ -0,0 +1,32 @@
dependencies {
compile project(':bukkit0')
compile 'org.bukkit.craftbukkitv1_10:craftbukkitv1_10:1.10'
}
processResources {
from('src/main/resources') {
include 'plugin.yml'
expand(
name: project.parent.name,
version: project.parent.version
)
}
}
apply plugin: 'com.github.johnrengelman.shadow'
// We only want the shadow jar produced
jar.enabled = false
shadowJar {
dependencies {
include(dependency(':bukkit0'))
include(dependency(':core'))
}
archiveName = "${parent.name}-${project.name}-${parent.version}.jar"
destinationDir = file '../target'
}
shadowJar.doLast {
task ->
ant.checksum file: task.archivePath
}
build.dependsOn(shadowJar);

View File

@ -0,0 +1,128 @@
package com.boydti.fawe.bukkit.v1_10;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.example.CharFaweChunk;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.util.MainUtil;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import net.minecraft.server.v1_10_R1.Block;
import net.minecraft.server.v1_10_R1.DataBits;
import net.minecraft.server.v1_10_R1.DataPalette;
import net.minecraft.server.v1_10_R1.DataPaletteBlock;
import net.minecraft.server.v1_10_R1.DataPaletteGlobal;
import net.minecraft.server.v1_10_R1.IBlockData;
import org.bukkit.Chunk;
public class BukkitChunk_1_10 extends CharFaweChunk<Chunk> {
public DataPaletteBlock[] sectionPalettes;
/**
* A FaweSections object represents a chunk and the blocks that you wish to change in it.
*
* @param parent
* @param x
* @param z
*/
public BukkitChunk_1_10(FaweQueue parent, int x, int z) {
super(parent, x, z);
}
@Override
public Chunk getNewChunk() {
return ((com.boydti.fawe.bukkit.v1_10.BukkitQueue_1_10) getParent()).getWorld().getChunkAt(getX(), getZ());
}
@Override
public CharFaweChunk<Chunk> copy(boolean shallow) {
BukkitChunk_1_10 value = (BukkitChunk_1_10) super.copy(shallow);
if (sectionPalettes != null) {
value.sectionPalettes = new DataPaletteBlock[16];
try {
Field fieldBits = DataPaletteBlock.class.getDeclaredField("b");
fieldBits.setAccessible(true);
Field fieldPalette = DataPaletteBlock.class.getDeclaredField("c");
fieldPalette.setAccessible(true);
Field fieldSize = DataPaletteBlock.class.getDeclaredField("e");
fieldSize.setAccessible(true);
for (int i = 0; i < sectionPalettes.length; i++) {
DataPaletteBlock current = sectionPalettes[i];
if (current == null) {
continue;
}
// Clone palette
DataPalette currentPalette = (DataPalette) fieldPalette.get(current);
if (!(currentPalette instanceof DataPaletteGlobal)) {
current.a(128, null);
}
DataPaletteBlock paletteBlock = newDataPaletteBlock();
currentPalette = (DataPalette) fieldPalette.get(current);
if (!(currentPalette instanceof DataPaletteGlobal)) {
throw new RuntimeException("Palette must be global!");
}
fieldPalette.set(paletteBlock, currentPalette);
// Clone size
fieldSize.set(paletteBlock, fieldSize.get(current));
// Clone palette
DataBits currentBits = (DataBits) fieldBits.get(current);
DataBits newBits = new DataBits(1, 0);
for (Field field : DataBits.class.getDeclaredFields()) {
field.setAccessible(true);
Object currentValue = field.get(currentBits);
if (currentValue instanceof long[]) {
currentValue = ((long[]) currentValue).clone();
}
field.set(newBits, currentValue);
}
fieldBits.set(paletteBlock, newBits);
value.sectionPalettes[i] = paletteBlock;
}
} catch (Throwable e) {
MainUtil.handleError(e);
}
}
return value;
}
public DataPaletteBlock newDataPaletteBlock() {
try {
return new DataPaletteBlock();
} catch (Throwable e) {
try {
Constructor<DataPaletteBlock> constructor = DataPaletteBlock.class.getDeclaredConstructor(IBlockData[].class);
return constructor.newInstance((Object) null);
} catch (Throwable e2) {
throw new RuntimeException(e2);
}
}
}
public void optimize() {
if (sectionPalettes != null) {
return;
}
char[][] arrays = getCombinedIdArrays();
IBlockData lastBlock = null;
char lastChar = Character.MAX_VALUE;
for (int layer = 0; layer < 16; layer++) {
if (getCount(layer) > 0) {
if (sectionPalettes == null) {
sectionPalettes = new DataPaletteBlock[16];
}
DataPaletteBlock palette = newDataPaletteBlock();
char[] blocks = getIdArray(layer);
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
char combinedId = blocks[FaweCache.CACHE_J[y][x][z]];
if (combinedId > 1) {
palette.setBlock(x, y, z, Block.getById(combinedId >> 4).fromLegacyData(combinedId & 0xF));
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,19 @@
package com.boydti.fawe.bukkit.v1_10;
import com.boydti.fawe.bukkit.ABukkitMain;
import com.boydti.fawe.bukkit.v0.BukkitEditSessionWrapper_0;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.object.EditSessionWrapper;
import com.sk89q.worldedit.EditSession;
public class BukkitMain_110 extends ABukkitMain {
@Override
public BukkitQueue_0 getQueue(String world) {
return new com.boydti.fawe.bukkit.v1_10.BukkitQueue_1_10(world);
}
@Override
public EditSessionWrapper getEditSessionWrapper(EditSession session) {
return new BukkitEditSessionWrapper_0(session);
}
}

View File

@ -0,0 +1,747 @@
package com.boydti.fawe.bukkit.v1_10;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.example.CharFaweChunk;
import com.boydti.fawe.object.BytePair;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.PseudoRandom;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.ReflectionUtils;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.internal.Constants;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import net.minecraft.server.v1_10_R1.Block;
import net.minecraft.server.v1_10_R1.BlockPosition;
import net.minecraft.server.v1_10_R1.Blocks;
import net.minecraft.server.v1_10_R1.ChunkCoordIntPair;
import net.minecraft.server.v1_10_R1.ChunkSection;
import net.minecraft.server.v1_10_R1.DataBits;
import net.minecraft.server.v1_10_R1.DataPalette;
import net.minecraft.server.v1_10_R1.DataPaletteBlock;
import net.minecraft.server.v1_10_R1.Entity;
import net.minecraft.server.v1_10_R1.EntityHuman;
import net.minecraft.server.v1_10_R1.EntityPlayer;
import net.minecraft.server.v1_10_R1.EntityTracker;
import net.minecraft.server.v1_10_R1.EntityTrackerEntry;
import net.minecraft.server.v1_10_R1.EntityTypes;
import net.minecraft.server.v1_10_R1.IBlockData;
import net.minecraft.server.v1_10_R1.NBTTagCompound;
import net.minecraft.server.v1_10_R1.NibbleArray;
import net.minecraft.server.v1_10_R1.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_10_R1.PacketPlayOutMapChunk;
import net.minecraft.server.v1_10_R1.PlayerChunk;
import net.minecraft.server.v1_10_R1.PlayerChunkMap;
import net.minecraft.server.v1_10_R1.TileEntity;
import net.minecraft.server.v1_10_R1.WorldServer;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.v1_10_R1.CraftChunk;
import org.bukkit.event.entity.CreatureSpawnEvent;
public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], DataPaletteBlock> {
private IBlockData air;
public BukkitQueue_1_10(final String world) {
super(world);
checkVersion("v1_10_R1");
try {
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
fieldAir.setAccessible(true);
air = (IBlockData) fieldAir.get(null);
if (adapter == null) {
setupAdapter(new com.boydti.fawe.bukkit.v1_10.FaweAdapter_1_10());
Fawe.debug("Using adapter: " + adapter);
Fawe.debug("=========================================");
}
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
@Override
public ChunkSection[] getCachedSections(World world, int cx, int cz) {
CraftChunk chunk = (CraftChunk) world.getChunkAt(cx, cz);
return chunk.getHandle().getSections();
}
@Override
public DataPaletteBlock getCachedSection(ChunkSection[] chunkSections, int cy) {
ChunkSection nibble = chunkSections[cy];
return nibble != null ? nibble.getBlocks() : null;
}
@Override
public int getCombinedId4Data(DataPaletteBlock lastSection, int x, int y, int z) {
IBlockData ibd = lastSection.a(x & 15, y & 15, z & 15);
Block block = ibd.getBlock();
int id = Block.getId(block);
if (FaweCache.hasData(id)) {
return (id << 4) + block.toLegacyData(ibd);
} else {
return id << 4;
}
}
@Override
public void refreshChunk(World world, Chunk chunk) {
if (!chunk.isLoaded()) {
return;
}
net.minecraft.server.v1_10_R1.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
ChunkCoordIntPair pos = nmsChunk.k(); // getPosition()
WorldServer w = (WorldServer) nmsChunk.getWorld();
PlayerChunkMap chunkMap = w.getPlayerChunkMap();
PlayerChunk playerChunk = chunkMap.getChunk(pos.x, pos.z);
if (playerChunk == null) {
return;
}
HashSet<EntityPlayer> set = new HashSet<EntityPlayer>(playerChunk.c);
EntityTracker tracker = w.getTracker();
// Get players
HashSet<EntityPlayer> players = new HashSet<>();
for (EntityHuman human : w.players) {
if (set.contains(human)) {
players.add((EntityPlayer) human);
}
}
if (players.size() == 0) {
return;
}
HashSet<EntityTrackerEntry> entities = new HashSet<>();
List<Entity>[] entitieSlices = playerChunk.chunk.getEntitySlices();
for (List<Entity> slice : entitieSlices) {
if (slice == null) {
continue;
}
for (Entity ent : slice) {
EntityTrackerEntry entry = tracker.trackedEntities.get(ent.getId());
if (entry == null) {
continue;
}
entities.add(entry);
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ent.getId());
for (EntityPlayer player : players) {
player.playerConnection.sendPacket(packet);
}
}
}
for (EntityPlayer player : players) {
player.playerConnection.networkManager.a();
}
// Send chunks
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(playerChunk.chunk, 65535);
for (EntityPlayer player : players) {
player.playerConnection.sendPacket(packet);
}
// send ents
for (List<Entity> slice : entitieSlices) {
if (slice == null) {
continue;
}
for (Entity ent : slice) {
EntityTrackerEntry entry = tracker.trackedEntities.get(ent.getId());
if (entry == null) {
continue;
}
try {
TaskManager.IMP.later(new Runnable() {
@Override
public void run() {
for (EntityPlayer player : players) {
boolean result = entry.trackedPlayers.remove(player);
if (result && ent != player) {
entry.updatePlayer(player);
}
}
}
}, 2);
} catch (Throwable e) {
MainUtil.handleError(e);
}
}
}
}
@Override
public boolean fixLighting(final FaweChunk pc, RelightMode mode) {
if (mode == RelightMode.NONE) {
return true;
}
try {
CharFaweChunk bc = (CharFaweChunk) pc;
Chunk chunk = (Chunk) bc.getChunk();
if (!chunk.isLoaded()) {
if (Fawe.get().getMainThread() != Thread.currentThread()) {
return false;
}
chunk.load(false);
}
net.minecraft.server.v1_10_R1.Chunk c = ((CraftChunk) chunk).getHandle();
final boolean flag = chunk.getWorld().getEnvironment() == Environment.NORMAL;
ChunkSection[] sections = c.getSections();
if (mode == RelightMode.ALL) {
for (int i = 0; i < sections.length; i++) {
ChunkSection section = sections[i];
if (section != null) {
section.a(new NibbleArray());
if (flag) {
section.b(new NibbleArray());
}
}
}
}
if (flag) {
if (mode == RelightMode.ALL) {
c.initLighting();
} else {
int i = c.g();
for (int x = 0; x < 16; ++x) {
for (int z = 0; z < 16; ++z) {
int l = 15;
int y = i + 16 - 1;
do {
int opacity = c.a(x, y, z).c();
if (opacity == 0 && l != 15) {
opacity = 1;
}
l -= opacity;
if (l > 0) {
ChunkSection section = sections[y >> 4];
if (section != null) {
section.a(x, y & 15, z, l);
}
}
--y;
} while (y > 0 && l > 0);
}
}
}
}
if (((bc.getTotalRelight() == 0) && mode == RelightMode.MINIMAL)) {
return true;
}
if (mode == RelightMode.ALL) {
bc = getPrevious(bc, c.getSections(), null, null, null, true);
}
int total = bc.getTotalCount();
net.minecraft.server.v1_10_R1.World w = c.world;
final int X = chunk.getX() << 4;
final int Z = chunk.getZ() << 4;
for (int j = sections.length - 1; j >= 0; j--) {
final Object section = sections[j];
if (section == null) {
continue;
}
if (((bc.getRelight(j) == 0) && mode == RelightMode.MINIMAL) || (bc.getCount(j) == 0 && mode != RelightMode.ALL) || ((bc.getCount(j) >= 4096) && (bc.getAir(j) == 0)) || bc.getAir(j) == 4096) {
continue;
}
final char[] array = bc.getIdArray(j);
if (array == null) {
continue;
}
if (mode == RelightMode.ALL) {
for (int k = array.length - 1; k >= 0; k--) {
final int x = FaweCache.CACHE_X[j][k];
final int y = FaweCache.CACHE_Y[j][k];
final int z = FaweCache.CACHE_Z[j][k];
if (this.isSurrounded(bc.getCombinedIdArrays(), x, y, z)) {
continue;
}
pos.c(X + x, y, Z + z);
w.w(pos);
}
continue;
}
for (int k = array.length - 1; k >= 0; k--) {
final int i = array[k];
final short id = (short) (i >> 4);
switch (id) { // Lighting
case 0:
continue;
default:
if (mode == RelightMode.MINIMAL) {
continue;
}
if (PseudoRandom.random.random(3) != 0) {
continue;
}
case 10:
case 11:
case 39:
case 40:
case 50:
case 51:
case 62:
case 74:
case 76:
case 89:
case 122:
case 124:
case 130:
case 138:
case 169:
final int x = FaweCache.CACHE_X[j][k];
final int y = FaweCache.CACHE_Y[j][k];
final int z = FaweCache.CACHE_Z[j][k];
if (this.isSurrounded(bc.getCombinedIdArrays(), x, y, z)) {
continue;
}
pos.c(X + x, y, Z + z);
w.w(pos);
}
}
}
return true;
} catch (Throwable e) {
if (Thread.currentThread() == Fawe.get().getMainThread()) {
MainUtil.handleError(e);
}
}
return false;
}
public boolean isSurrounded(final char[][] sections, final int x, final int y, final int z) {
return this.isSolid(this.getId(sections, x, y + 1, z))
&& this.isSolid(this.getId(sections, x + 1, y - 1, z))
&& this.isSolid(this.getId(sections, x - 1, y, z))
&& this.isSolid(this.getId(sections, x, y, z + 1))
&& this.isSolid(this.getId(sections, x, y, z - 1));
}
public boolean isSolid(final int i) {
if (i != 0) {
final Material material = Material.getMaterial(i);
return (material != null) && Material.getMaterial(i).isOccluding();
}
return false;
}
public int getId(final char[][] sections, final int x, final int y, final int z) {
if ((x < 0) || (x > 15) || (z < 0) || (z > 15)) {
return 1;
}
if ((y < 0) || (y > 255)) {
return 1;
}
final int i = FaweCache.CACHE_I[y][x][z];
final char[] section = sections[i];
if (section == null) {
return 0;
}
final int j = FaweCache.CACHE_J[y][x][z];
return section[j] >> 4;
}
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
Class<? extends ChunkSection> clazz = section.getClass();
Field fieldTickingBlockCount = clazz.getDeclaredField("tickingBlockCount");
Field fieldNonEmptyBlockCount = clazz.getDeclaredField("nonEmptyBlockCount");
fieldTickingBlockCount.setAccessible(true);
fieldNonEmptyBlockCount.setAccessible(true);
fieldTickingBlockCount.set(section, tickingBlockCount);
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
}
public void setPalette(ChunkSection section, DataPaletteBlock palette) throws NoSuchFieldException, IllegalAccessException {
Field fieldSection = ChunkSection.class.getDeclaredField("blockIds");
fieldSection.setAccessible(true);
fieldSection.set(section, palette);
}
public ChunkSection newChunkSection(int y2, boolean flag, char[] array) {
try {
if (array == null) {
return new ChunkSection(y2, flag);
} else {
return new ChunkSection(y2, flag, array);
}
} catch (Throwable e) {
try {
if (array == null) {
Constructor<ChunkSection> constructor = ChunkSection.class.getDeclaredConstructor(int.class, boolean.class, IBlockData[].class);
return constructor.newInstance(y2, flag, (IBlockData[]) null);
} else {
Constructor<ChunkSection> constructor = ChunkSection.class.getDeclaredConstructor(int.class, boolean.class, char[].class, IBlockData[].class);
return constructor.newInstance(y2, flag, array, (IBlockData[]) null);
}
} catch (Throwable e2) {
throw new RuntimeException(e2);
}
}
}
@Override
public CharFaweChunk getPrevious(CharFaweChunk fs, ChunkSection[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
Map<BlockPosition, TileEntity> tiles = (Map<BlockPosition, TileEntity>) tilesGeneric;
Collection<Entity>[] entities = (Collection<Entity>[]) entitiesGeneric;
CharFaweChunk previous = (CharFaweChunk) getFaweChunk(fs.getX(), fs.getZ());
// Copy blocks
char[][] idPrevious = new char[16][];
for (int layer = 0; layer < sections.length; layer++) {
if (fs.getCount(layer) != 0 || all) {
ChunkSection section = sections[layer];
if (section != null) {
short solid = 0;
char[] previousLayer = idPrevious[layer] = new char[4096];
DataPaletteBlock blocks = section.getBlocks();
for (int j = 0; j < 4096; j++) {
int x = FaweCache.CACHE_X[0][j];
int y = FaweCache.CACHE_Y[0][j];
int z = FaweCache.CACHE_Z[0][j];
IBlockData ibd = blocks.a(x, y, z);
Block block = ibd.getBlock();
int combined = Block.getId(block);
if (FaweCache.hasData(combined)) {
combined = (combined << 4) + block.toLegacyData(ibd);
} else {
combined = combined << 4;
}
if (combined > 1) {
solid++;
}
previousLayer[j] = (char) combined;
}
previous.count[layer] = solid;
previous.air[layer] = (short) (4096 - solid);
}
}
}
previous.ids = idPrevious;
// Copy tiles
if (tiles != null) {
for (Map.Entry<BlockPosition, TileEntity> entry : tiles.entrySet()) {
TileEntity tile = entry.getValue();
NBTTagCompound tag = new NBTTagCompound();
BlockPosition pos = entry.getKey();
CompoundTag nativeTag = getTag(tile);
previous.setTile(pos.getX() & 15, pos.getY(), pos.getZ() & 15, nativeTag);
}
}
// Copy entities
if (entities != null) {
for (Collection<Entity> entityList : entities) {
for (Entity ent : entityList) {
if (ent instanceof EntityPlayer || (!createdEntities.isEmpty() && createdEntities.contains(ent.getUniqueID()))) {
continue;
}
int x = ((int) Math.round(ent.locX) & 15);
int z = ((int) Math.round(ent.locZ) & 15);
int y = (int) Math.round(ent.locY);
int i = FaweCache.CACHE_I[y][x][z];
char[] array = fs.getIdArray(i);
if (array == null) {
continue;
}
int j = FaweCache.CACHE_J[y][x][z];
if (array[j] != 0) {
String id = EntityTypes.b(ent);
if (id != null) {
NBTTagCompound tag = new NBTTagCompound();
ent.e(tag); // readEntityIntoTag
CompoundTag nativeTag = (CompoundTag) methodToNative.invoke(adapter, tag);
Map<String, Tag> map = ReflectionUtils.getMap(nativeTag.getValue());
map.put("Id", new StringTag(id));
previous.setEntity(nativeTag);
}
}
}
}
}
return previous;
}
private BlockPosition.MutableBlockPosition pos = new BlockPosition.MutableBlockPosition(0, 0, 0);
@Override
public CompoundTag getTileEntity(Chunk chunk, int x, int y, int z) {
Map<BlockPosition, TileEntity> tiles = ((CraftChunk) chunk).getHandle().getTileEntities();
pos.c(x, y, z);
TileEntity tile = tiles.get(pos);
return tile != null ? getTag(tile) : null;
}
public CompoundTag getTag(TileEntity tile) {
try {
NBTTagCompound tag = new NBTTagCompound();
tile.save(tag); // readTagIntoEntity
return (CompoundTag) methodToNative.invoke(adapter, tag);
} catch (Exception e) {
MainUtil.handleError(e);
return null;
}
}
@Override
public Chunk getChunk(World world, int x, int z) {
return world.getChunkAt(x, z);
}
@Override
public boolean setComponents(final FaweChunk fc, RunnableVal<FaweChunk> changeTask) {
final com.boydti.fawe.bukkit.v1_10.BukkitChunk_1_10 fs = (com.boydti.fawe.bukkit.v1_10.BukkitChunk_1_10) fc;
final Chunk chunk = (Chunk) fs.getChunk();
final World world = chunk.getWorld();
chunk.load(true);
try {
final boolean flag = world.getEnvironment() == Environment.NORMAL;
net.minecraft.server.v1_10_R1.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
net.minecraft.server.v1_10_R1.World nmsWorld = nmsChunk.world;
ChunkSection[] sections = nmsChunk.getSections();
Class<? extends net.minecraft.server.v1_10_R1.Chunk> clazzChunk = nmsChunk.getClass();
final Field ef = clazzChunk.getDeclaredField("entitySlices");
final Collection<Entity>[] entities = (Collection<Entity>[]) ef.get(nmsChunk);
Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities();
// Remove entities
for (int i = 0; i < entities.length; i++) {
int count = fs.getCount(i);
if (count == 0) {
continue;
} else if (count >= 4096) {
entities[i].clear();
} else {
char[] array = fs.getIdArray(i);
Collection<Entity> ents = new ArrayList<>(entities[i]);
for (Entity entity : ents) {
if (entity instanceof EntityPlayer) {
continue;
}
int x = ((int) Math.round(entity.locX) & 15);
int z = ((int) Math.round(entity.locZ) & 15);
int y = (int) Math.round(entity.locY);
if (array == null || y < 0 || y > 255) {
continue;
}
if (y < 0 || y > 255 || array[FaweCache.CACHE_J[y][x][z]] != 0) {
nmsWorld.removeEntity(entity);
}
}
}
}
HashSet<UUID> entsToRemove = fs.getEntityRemoves();
if (entsToRemove.size() > 0) {
for (int i = 0; i < entities.length; i++) {
Collection<Entity> ents = new ArrayList<>(entities[i]);
for (Entity entity : ents) {
if (entsToRemove.contains(entity.getUniqueID())) {
nmsWorld.removeEntity(entity);
}
}
}
}
// Set entities
Set<UUID> createdEntities = new HashSet<>();
Set<CompoundTag> entitiesToSpawn = fs.getEntities();
for (CompoundTag nativeTag : entitiesToSpawn) {
Map<String, Tag> entityTagMap = ReflectionUtils.getMap(nativeTag.getValue());
StringTag idTag = (StringTag) entityTagMap.get("Id");
ListTag posTag = (ListTag) entityTagMap.get("Pos");
ListTag rotTag = (ListTag) entityTagMap.get("Rotation");
if (idTag == null || posTag == null || rotTag == null) {
Fawe.debug("Unknown entity tag: " + nativeTag);
continue;
}
double x = posTag.getDouble(0);
double y = posTag.getDouble(1);
double z = posTag.getDouble(2);
float yaw = rotTag.getFloat(0);
float pitch = rotTag.getFloat(1);
String id = idTag.getValue();
Entity entity = EntityTypes.createEntityByName(id, nmsWorld);
if (entity != null) {
UUID uuid = entity.getUniqueID();
entityTagMap.put("UUIDMost", new LongTag(uuid.getMostSignificantBits()));
entityTagMap.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits()));
if (nativeTag != null) {
NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(adapter, nativeTag);
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
tag.remove(name);
}
entity.f(tag);
}
entity.setLocation(x, y, z, yaw, pitch);
nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM);
createdEntities.add(entity.getUniqueID());
}
}
// Change task?
if (changeTask != null) {
CharFaweChunk previous = getPrevious(fs, sections, tiles, entities, createdEntities, false);
changeTask.run(previous);
}
// Trim tiles
Set<Entry<BlockPosition, TileEntity>> entryset = tiles.entrySet();
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = entryset.iterator();
while (iterator.hasNext()) {
Map.Entry<BlockPosition, TileEntity> tile = iterator.next();
BlockPosition pos = tile.getKey();
int lx = pos.getX() & 15;
int ly = pos.getY();
int lz = pos.getZ() & 15;
int j = FaweCache.CACHE_I[ly][lx][lz];
char[] array = fs.getIdArray(j);
if (array == null) {
continue;
}
int k = FaweCache.CACHE_J[ly][lx][lz];
if (array[k] != 0) {
tile.getValue().invalidateBlockCache();
iterator.remove();
}
}
// Set blocks
for (int j = 0; j < sections.length; j++) {
int count = fs.getCount(j);
if (count == 0) {
continue;
}
final char[] array = fs.getIdArray(j);
if (array == null) {
continue;
}
ChunkSection section = sections[j];
if (section == null) {
if (fs.sectionPalettes != null && fs.sectionPalettes[j] != null) {
section = sections[j] = newChunkSection(j << 4, flag, null);
setPalette(section, fs.sectionPalettes[j]);
setCount(0, count - fs.getAir(j), section);
continue;
} else {
sections[j] = newChunkSection(j << 4, flag, array);
}
continue;
} else if (count >= 4096) {
if (fs.sectionPalettes != null && fs.sectionPalettes[j] != null) {
setPalette(section, fs.sectionPalettes[j]);
setCount(0, count - fs.getAir(j), section);
continue;
} else {
sections[j] = newChunkSection(j << 4, flag, array);
}
continue;
}
DataPaletteBlock nibble = section.getBlocks();
Field fieldBits = nibble.getClass().getDeclaredField("b");
fieldBits.setAccessible(true);
DataBits bits = (DataBits) fieldBits.get(nibble);
Field fieldPalette = nibble.getClass().getDeclaredField("c");
fieldPalette.setAccessible(true);
DataPalette palette = (DataPalette) fieldPalette.get(nibble);
int nonEmptyBlockCount = 0;
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
char combinedId = array[FaweCache.CACHE_J[y][x][z]];
switch (combinedId) {
case 0:
IBlockData existing = nibble.a(x, y, z);
if (existing != air) {
nonEmptyBlockCount++;
}
continue;
case 1:
nibble.setBlock(x, y, z, Blocks.AIR.getBlockData());
continue;
default:
nonEmptyBlockCount++;
nibble.setBlock(x, y, z, Block.getById(combinedId >> 4).fromLegacyData(combinedId & 0xF));
}
}
}
}
setCount(0, nonEmptyBlockCount, section);
}
// Set biomes
int[][] biomes = fs.biomes;
if (biomes != null) {
for (int x = 0; x < 16; x++) {
int[] array = biomes[x];
if (array == null) {
continue;
}
for (int z = 0; z < 16; z++) {
int biome = array[z];
if (biome == 0) {
continue;
}
nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
}
}
}
// Set tiles
Map<BytePair, CompoundTag> tilesToSpawn = fs.getTiles();
int bx = fs.getX() << 4;
int bz = fs.getZ() << 4;
for (Map.Entry<BytePair, CompoundTag> entry : tilesToSpawn.entrySet()) {
CompoundTag nativeTag = entry.getValue();
BytePair pair = entry.getKey();
BlockPosition pos = new BlockPosition(MathMan.unpair16x(pair.pair[0]) + bx, pair.pair[1] & 0xFF, MathMan.unpair16y(pair.pair[0]) + bz); // Set pos
TileEntity tileEntity = nmsWorld.getTileEntity(pos);
if (tileEntity != null) {
NBTTagCompound tag = (NBTTagCompound) methodFromNative.invoke(adapter, nativeTag);
tileEntity.a(tag); // ReadTagIntoTile
}
}
} catch (Throwable e) {
MainUtil.handleError(e);
}
final int[][] biomes = fs.getBiomeArray();
final Biome[] values = Biome.values();
if (biomes != null) {
for (int x = 0; x < 16; x++) {
final int[] array = biomes[x];
if (array == null) {
continue;
}
for (int z = 0; z < 16; z++) {
final int biome = array[z];
if (biome == 0) {
continue;
}
chunk.getBlock(x, 0, z).setBiome(values[biome]);
}
}
}
sendChunk(fs, null);
return true;
}
@Deprecated
public boolean unloadChunk(final String world, final Chunk chunk) {
net.minecraft.server.v1_10_R1.Chunk c = ((CraftChunk) chunk).getHandle();
c.mustSave = false;
if (chunk.isLoaded()) {
chunk.unload(false, false);
}
return true;
}
@Override
public FaweChunk getFaweChunk(int x, int z) {
return new com.boydti.fawe.bukkit.v1_10.BukkitChunk_1_10(this, x, z);
}
}

View File

@ -0,0 +1,373 @@
package com.boydti.fawe.bukkit.v1_10;
import com.google.common.base.Preconditions;
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.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.BaseBlock;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.internal.Constants;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import net.minecraft.server.v1_10_R1.BiomeBase;
import net.minecraft.server.v1_10_R1.BlockPosition;
import net.minecraft.server.v1_10_R1.EntityTypes;
import net.minecraft.server.v1_10_R1.NBTBase;
import net.minecraft.server.v1_10_R1.NBTTagByte;
import net.minecraft.server.v1_10_R1.NBTTagByteArray;
import net.minecraft.server.v1_10_R1.NBTTagCompound;
import net.minecraft.server.v1_10_R1.NBTTagDouble;
import net.minecraft.server.v1_10_R1.NBTTagEnd;
import net.minecraft.server.v1_10_R1.NBTTagFloat;
import net.minecraft.server.v1_10_R1.NBTTagInt;
import net.minecraft.server.v1_10_R1.NBTTagIntArray;
import net.minecraft.server.v1_10_R1.NBTTagList;
import net.minecraft.server.v1_10_R1.NBTTagLong;
import net.minecraft.server.v1_10_R1.NBTTagShort;
import net.minecraft.server.v1_10_R1.NBTTagString;
import net.minecraft.server.v1_10_R1.TileEntity;
import net.minecraft.server.v1_10_R1.World;
import net.minecraft.server.v1_10_R1.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_10_R1.CraftServer;
import org.bukkit.craftbukkit.v1_10_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_10_R1.block.CraftBlock;
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity;
import org.bukkit.event.entity.CreatureSpawnEvent;
public final class FaweAdapter_1_10 implements BukkitImplAdapter
{
private final Logger logger = Logger.getLogger(getClass().getCanonicalName());
private final Field nbtListTagListField;
private final Method nbtCreateTagMethod;
public FaweAdapter_1_10()
throws NoSuchFieldException, NoSuchMethodException
{
CraftServer.class.cast(Bukkit.getServer());
this.nbtListTagListField = NBTTagList.class.getDeclaredField("list");
this.nbtListTagListField.setAccessible(true);
this.nbtCreateTagMethod = NBTBase.class.getDeclaredMethod("createTag", new Class[] { Byte.TYPE });
this.nbtCreateTagMethod.setAccessible(true);
}
private static void readTagIntoTileEntity(NBTTagCompound tag, TileEntity tileEntity)
{
tileEntity.a(tag);
}
private static void readTileEntityIntoTag(TileEntity tileEntity, NBTTagCompound tag)
{
tileEntity.save(tag);
}
@Nullable
private static String getEntityId(net.minecraft.server.v1_10_R1.Entity entity)
{
return EntityTypes.b(entity);
}
@Nullable
private static net.minecraft.server.v1_10_R1.Entity createEntityFromId(String id, World world)
{
return EntityTypes.createEntityByName(id, world);
}
private static void readTagIntoEntity(NBTTagCompound tag, net.minecraft.server.v1_10_R1.Entity entity)
{
entity.f(tag);
}
private static void readEntityIntoTag(net.minecraft.server.v1_10_R1.Entity entity, NBTTagCompound tag)
{
entity.e(tag);
}
public int getBlockId(Material material)
{
return material.getId();
}
public Material getMaterial(int id)
{
return Material.getMaterial(id);
}
public int getBiomeId(Biome biome)
{
BiomeBase mcBiome = CraftBlock.biomeToBiomeBase(biome);
return mcBiome != null ? BiomeBase.a(mcBiome) : 0;
}
public Biome getBiome(int id)
{
BiomeBase mcBiome = BiomeBase.getBiome(id);
return CraftBlock.biomeBaseToBiome(mcBiome);
}
public BaseBlock getBlock(Location location)
{
Preconditions.checkNotNull(location);
CraftWorld craftWorld = (CraftWorld)location.getWorld();
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
Block bukkitBlock = location.getBlock();
BaseBlock block = new BaseBlock(bukkitBlock.getTypeId(), bukkitBlock.getData());
TileEntity te = craftWorld.getHandle().getTileEntity(new BlockPosition(x, y, z));
if (te != null)
{
NBTTagCompound tag = new NBTTagCompound();
readTileEntityIntoTag(te, tag);
block.setNbtData((CompoundTag)toNative(tag));
}
return block;
}
public boolean setBlock(Location location, BaseBlock block, boolean notifyAndLight)
{
Preconditions.checkNotNull(location);
Preconditions.checkNotNull(block);
CraftWorld craftWorld = (CraftWorld)location.getWorld();
int x = location.getBlockX();
int y = location.getBlockY();
int z = location.getBlockZ();
boolean changed = location.getBlock().setTypeIdAndData(block.getId(), (byte)block.getData(), notifyAndLight);
CompoundTag nativeTag = block.getNbtData();
if (nativeTag != null)
{
TileEntity tileEntity = craftWorld.getHandle().getTileEntity(new BlockPosition(x, y, z));
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);
}
}
return changed;
}
public BaseEntity getEntity(org.bukkit.entity.Entity entity)
{
Preconditions.checkNotNull(entity);
CraftEntity craftEntity = (CraftEntity)entity;
net.minecraft.server.v1_10_R1.Entity mcEntity = craftEntity.getHandle();
String id = getEntityId(mcEntity);
if (id != null)
{
NBTTagCompound tag = new NBTTagCompound();
readEntityIntoTag(mcEntity, tag);
return new BaseEntity(id, (CompoundTag)toNative(tag));
}
return null;
}
@Nullable
public org.bukkit.entity.Entity createEntity(Location location, BaseEntity state)
{
Preconditions.checkNotNull(location);
Preconditions.checkNotNull(state);
CraftWorld craftWorld = (CraftWorld)location.getWorld();
WorldServer worldServer = craftWorld.getHandle();
net.minecraft.server.v1_10_R1.Entity createdEntity = createEntityFromId(state.getTypeId(), 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, CreatureSpawnEvent.SpawnReason.CUSTOM);
return createdEntity.getBukkitEntity();
}
return null;
}
private Tag toNative(NBTBase foreign)
{
if (foreign == null) {
return null;
}
if ((foreign instanceof NBTTagCompound))
{
Map<String, Tag> values = new HashMap();
Set<String> foreignKeys = ((NBTTagCompound)foreign).c();
for (String str : foreignKeys)
{
NBTBase base = ((NBTTagCompound)foreign).get(str);
values.put(str, toNative(base));
}
return new CompoundTag(values);
}
if ((foreign instanceof NBTTagByte)) {
return new ByteTag(((NBTTagByte)foreign).g());
}
if ((foreign instanceof NBTTagByteArray)) {
return new ByteArrayTag(((NBTTagByteArray)foreign).c());
}
if ((foreign instanceof NBTTagDouble)) {
return new DoubleTag(((NBTTagDouble)foreign).h());
}
if ((foreign instanceof NBTTagFloat)) {
return new FloatTag(((NBTTagFloat)foreign).i());
}
if ((foreign instanceof NBTTagInt)) {
return new IntTag(((NBTTagInt)foreign).e());
}
if ((foreign instanceof NBTTagIntArray)) {
return new IntArrayTag(((NBTTagIntArray)foreign).d());
}
if ((foreign instanceof NBTTagList)) {
try
{
return toNativeList((NBTTagList)foreign);
}
catch (Throwable e)
{
this.logger.log(Level.WARNING, "Failed to convert NBTTagList", e);
return new ListTag(ByteTag.class, new ArrayList());
}
}
if ((foreign instanceof NBTTagLong)) {
return new LongTag(((NBTTagLong)foreign).d());
}
if ((foreign instanceof NBTTagShort)) {
return new ShortTag(((NBTTagShort)foreign).f());
}
if ((foreign instanceof NBTTagString)) {
return new StringTag(((NBTTagString)foreign).c_());
}
if ((foreign instanceof NBTTagEnd)) {
return new EndTag();
}
throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName());
}
private ListTag toNativeList(NBTTagList foreign)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException
{
List<Tag> values = new ArrayList();
int type = foreign.getTypeId();
List foreignList = (List)this.nbtListTagListField.get(foreign);
for (int i = 0; i < foreign.size(); i++)
{
NBTBase element = (NBTBase)foreignList.get(i);
values.add(toNative(element));
}
Class<? extends Tag> cls = NBTConstants.getClassFromType(type);
return new ListTag(cls, values);
}
private NBTBase fromNative(Tag foreign)
{
if (foreign == null) {
return null;
}
Map.Entry<String, Tag> entry;
if ((foreign instanceof CompoundTag))
{
NBTTagCompound tag = new NBTTagCompound();
for (Iterator localIterator = ((CompoundTag)foreign)
.getValue().entrySet().iterator(); localIterator.hasNext();)
{
entry = (Map.Entry)localIterator.next();
tag.set((String)entry.getKey(), fromNative((Tag)entry.getValue()));
}
return tag;
}
if ((foreign instanceof ByteTag)) {
return new NBTTagByte(((ByteTag)foreign).getValue().byteValue());
}
if ((foreign instanceof ByteArrayTag)) {
return new NBTTagByteArray(((ByteArrayTag)foreign).getValue());
}
if ((foreign instanceof DoubleTag)) {
return new NBTTagDouble(((DoubleTag)foreign).getValue().doubleValue());
}
if ((foreign instanceof FloatTag)) {
return new NBTTagFloat(((FloatTag)foreign).getValue().floatValue());
}
if ((foreign instanceof IntTag)) {
return new NBTTagInt(((IntTag)foreign).getValue().intValue());
}
if ((foreign instanceof IntArrayTag)) {
return new NBTTagIntArray(((IntArrayTag)foreign).getValue());
}
if ((foreign instanceof ListTag))
{
NBTTagList tag = new NBTTagList();
ListTag foreignList = (ListTag)foreign;
for (Tag t : foreignList.getValue()) {
tag.add(fromNative(t));
}
return tag;
}
if ((foreign instanceof LongTag)) {
return new NBTTagLong(((LongTag)foreign).getValue().longValue());
}
if ((foreign instanceof ShortTag)) {
return new NBTTagShort(((ShortTag)foreign).getValue().shortValue());
}
if ((foreign instanceof StringTag)) {
return new NBTTagString(((StringTag)foreign).getValue());
}
if ((foreign instanceof EndTag)) {
try
{
return (NBTBase)this.nbtCreateTagMethod.invoke(null, new Object[] { Byte.valueOf((byte) 0) });
}
catch (Exception e)
{
return null;
}
}
throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName());
}
}

View File

@ -0,0 +1,49 @@
name: ${name}
main: com.boydti.fawe.bukkit.v1_10.BukkitMain_110
version: ${version}
description: Fast Async WorldEdit plugin
authors: [Empire92]
loadbefore: [WorldEdit]
load: STARTUP
database: false
#softdepend: [WorldGuard, PlotSquared, MCore, Factions, GriefPrevention, Residence, Towny, PlotMe, PreciousStones]
commands:
wea:
description: (FAWE) Bypass WorldEdit processing and area restrictions
aliases: [weanywhere,worldeditanywhere,/wea,/weanywhere,/worldeditanywhere]
usage: "Vault is required for the toggle. Optionally, you can set the permission fawe.bypass"
fixlighting:
description: (FAWE) Fix the lighting in your current chunk
aliases: [/fixlighting]
stream:
description: (FAWE) Stream a schematic into the world
aliases: [/stream]
fawe:
description: (FAWE) Reload the plugin
aliases: [/fawe,/fawereload]
select:
description: (FAWE) Select your current WorldEdit Region.
aliases: [/select,wer,/wer,worldeditregion,/worldeditregion,/region]
frb:
description: (FAWE) Rollback an edit
aliases: [fawerollback,fawerb,/uu,/rb,/frb,/fawerollback,/fawerb]
fcancel:
description: (FAWE) Cancel your edit
aliases: [fawecancel,/fcancel,/cancel,/fawecancel]
'/p':
description: VoxelSniper perform command
aliases: [perform,/perform]
'/d':
description: VoxelSniper default command
aliases: [default,/default]
permissions:
fawe.bypass:
default: false
fawe.admin:
default: false
fawe.stream:
default: false
fawe.fixlighting:
default: false
fawe.reload:
default: false

View File

@ -18,7 +18,7 @@ public class SetQueue {
*/
public static final SetQueue IMP = new SetQueue();
public static enum QueueStage {
public enum QueueStage {
INACTIVE, ACTIVE, NONE;
}

View File

@ -1,3 +1,3 @@
rootProject.name = 'FastAsyncWorldEdit'
include 'core', 'bukkit0', 'bukkit19', 'bukkit18', 'forge189', 'forge1710', 'sponge'
include 'core', 'bukkit0', 'bukkit19', 'bukkit110', 'bukkit18', 'forge189', 'forge1710', 'sponge'