This commit is contained in:
Jesse Boyd 2017-03-08 04:59:38 +11:00
parent 50d80b3d1c
commit b4e4ffa0fc
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
2 changed files with 159 additions and 94 deletions

View File

@ -1,3 +1,4 @@
package com.boydti.fawe.bukkit.v1_10; package com.boydti.fawe.bukkit.v1_10;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
@ -16,6 +17,8 @@ import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.internal.Constants;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -25,7 +28,6 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import net.minecraft.server.v1_10_R1.Block; import net.minecraft.server.v1_10_R1.Block;
import net.minecraft.server.v1_10_R1.BlockPosition; import net.minecraft.server.v1_10_R1.BlockPosition;
import net.minecraft.server.v1_10_R1.ChunkSection;
import net.minecraft.server.v1_10_R1.DataBits; import net.minecraft.server.v1_10_R1.DataBits;
import net.minecraft.server.v1_10_R1.DataPalette; import net.minecraft.server.v1_10_R1.DataPalette;
import net.minecraft.server.v1_10_R1.DataPaletteBlock; import net.minecraft.server.v1_10_R1.DataPaletteBlock;
@ -38,7 +40,6 @@ import net.minecraft.server.v1_10_R1.NBTTagCompound;
import net.minecraft.server.v1_10_R1.TileEntity; import net.minecraft.server.v1_10_R1.TileEntity;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.craftbukkit.v1_10_R1.CraftChunk;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> { public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
@ -173,70 +174,121 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
getChunk().load(true); getChunk().load(true);
} }
private void removeEntity(Entity entity) {
entity.b(false);
entity.die();
entity.valid = false;
}
public void storeBiomes(byte[] biomes) {
this.biomes = Arrays.copyOf(biomes, biomes.length);
}
public boolean storeEntity(Entity ent) throws InvocationTargetException, IllegalAccessException {
if (ent instanceof EntityPlayer) {
return false;
}
int x = ((int) Math.round(ent.locX) & 15);
int z = ((int) Math.round(ent.locZ) & 15);
int y = ((int) Math.round(ent.locY) & 0xFF);
int i = FaweCache.CACHE_I[y][z][x];
int j = FaweCache.CACHE_J[y][z][x];
String id = EntityTypes.b(ent);
if (id != null) {
NBTTagCompound tag = new NBTTagCompound();
ent.e(tag); // readEntityIntoTag
CompoundTag nativeTag = (CompoundTag) getParent().methodToNative.invoke(getParent().adapter, tag);
Map<String, Tag> map = ReflectionUtils.getMap(nativeTag.getValue());
map.put("Id", new StringTag(id));
setEntity(nativeTag);
return true;
} else {
return false;
}
}
public boolean storeTile(TileEntity tile, BlockPosition pos) {
NBTTagCompound tag = new NBTTagCompound();
CompoundTag nativeTag = getParent().getTag(tile);
setTile(pos.getX() & 15, pos.getY(), pos.getZ() & 15, nativeTag);
return true;
}
@Override @Override
public FaweChunk call() { public FaweChunk call() {
try { try {
BukkitChunk_1_10_Copy copy = getParent().getChangeTask() != null ? new BukkitChunk_1_10_Copy(getParent(), getX(), getZ()) : null;
final Chunk chunk = this.getChunk(); final Chunk chunk = this.getChunk();
final World world = chunk.getWorld(); final World world = chunk.getWorld();
int bx = this.getX() << 4; int bx = this.getX() << 4;
int bz = this.getZ() << 4; int bz = this.getZ() << 4;
final boolean flag = world.getEnvironment() == World.Environment.NORMAL; final boolean flag = world.getEnvironment() == World.Environment.NORMAL;
net.minecraft.server.v1_10_R1.Chunk nmsChunk = ((CraftChunk) chunk).getHandle(); net.minecraft.server.v1_10_R1.Chunk nmsChunk = ((org.bukkit.craftbukkit.v1_10_R1.CraftChunk) chunk).getHandle();
nmsChunk.f(true); // Set Modified nmsChunk.f(true); // Set Modified
nmsChunk.mustSave = true; nmsChunk.mustSave = true;
net.minecraft.server.v1_10_R1.World nmsWorld = nmsChunk.world; net.minecraft.server.v1_10_R1.World nmsWorld = nmsChunk.world;
ChunkSection[] sections = nmsChunk.getSections(); net.minecraft.server.v1_10_R1.ChunkSection[] sections = nmsChunk.getSections();
Class<? extends net.minecraft.server.v1_10_R1.Chunk> clazzChunk = nmsChunk.getClass(); final Collection<net.minecraft.server.v1_10_R1.Entity>[] entities = (Collection<net.minecraft.server.v1_10_R1.Entity>[]) getParent().getEntitySlices.invoke(nmsChunk);
final Collection<Entity>[] entities = (Collection<Entity>[]) getParent().getEntitySlices.invoke(nmsChunk); Map<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> tiles = nmsChunk.getTileEntities();
Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities();
// Set heightmap // Set heightmap
getParent().setHeightMap(this, heightMap); getParent().setHeightMap(this, heightMap);
// Remove entities // Remove entities
for (int i = 0; i < entities.length; i++) { HashSet<UUID> entsToRemove = this.getEntityRemoves();
int count = this.getCount(i); if (!entsToRemove.isEmpty()) {
if (count == 0) { for (int i = 0; i < entities.length; i++) {
continue; Collection<net.minecraft.server.v1_10_R1.Entity> ents = entities[i];
} else if (count >= 4096) {
Collection<Entity> ents = entities[i];
if (!ents.isEmpty()) { if (!ents.isEmpty()) {
synchronized (BukkitQueue_0.class) { Iterator<net.minecraft.server.v1_10_R1.Entity> iter = ents.iterator();
ents.clear(); while (iter.hasNext()) {
} net.minecraft.server.v1_10_R1.Entity entity = iter.next();
} if (entsToRemove.contains(entity.getUniqueID())) {
} else { if (copy != null) {
Collection<Entity> ents = entities[i]; copy.storeEntity(entity);
if (!ents.isEmpty()) {
char[] array = this.getIdArray(i);
if (array == null || entities[i] == null || entities[i].isEmpty()) continue;
Entity[] entsArr = ents.toArray(new Entity[ents.size()]);
synchronized (BukkitQueue_0.class) {
for (Entity entity : entsArr) {
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 (y < 0 || y > 255) continue;
if (array[FaweCache.CACHE_J[y][z][x]] != 0) {
nmsWorld.removeEntity(entity);
} }
removeEntity(entity);
iter.remove();
} }
} }
} }
} }
} }
HashSet<UUID> entsToRemove = this.getEntityRemoves(); for (int i = 0; i < entities.length; i++) {
if (!entsToRemove.isEmpty()) { int count = this.getCount(i);
synchronized (BukkitQueue_0.class) { if (count == 0) {
for (int i = 0; i < entities.length; i++) { continue;
Collection<Entity> ents = entities[i]; } else if (count >= 4096) {
if (ents.isEmpty()) { Collection<net.minecraft.server.v1_10_R1.Entity> ents = entities[i];
Entity[] entsArr = ents.toArray(new Entity[ents.size()]); if (!ents.isEmpty()) {
for (Entity entity : entsArr) { if (copy != null) {
if (entsToRemove.contains(entity.getUniqueID())) { for (net.minecraft.server.v1_10_R1.Entity entity : ents) {
nmsWorld.removeEntity(entity); copy.storeEntity(entity);
}
}
synchronized (BukkitQueue_0.class) {
ents.clear();
}
}
} else {
Collection<net.minecraft.server.v1_10_R1.Entity> ents = entities[i];
if (!ents.isEmpty()) {
char[] array = this.getIdArray(i);
if (array == null) continue;
Iterator<net.minecraft.server.v1_10_R1.Entity> iter = ents.iterator();
while (iter.hasNext()) {
net.minecraft.server.v1_10_R1.Entity entity = iter.next();
if (entity instanceof net.minecraft.server.v1_10_R1.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 (y < 0 || y > 255) continue;
if (array[FaweCache.CACHE_J[y][z][x]] != 0) {
if (copy != null) {
copy.storeEntity(entity);
} }
iter.remove();
removeEntity(entity);
} }
} }
} }
@ -281,17 +333,12 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
} }
} }
} }
// Change task?
if (getParent().getChangeTask() != null) {
BukkitChunk_1_10 previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false);
getParent().getChangeTask().run(previous, this);
}
// Trim tiles // Trim tiles
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator(); Iterator<Map.Entry<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity>> iterator = tiles.entrySet().iterator();
HashMap<BlockPosition, TileEntity> toRemove = null; HashMap<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> toRemove = null;
while (iterator.hasNext()) { while (iterator.hasNext()) {
Map.Entry<BlockPosition, TileEntity> tile = iterator.next(); Map.Entry<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> tile = iterator.next();
BlockPosition pos = tile.getKey(); net.minecraft.server.v1_10_R1.BlockPosition pos = tile.getKey();
int lx = pos.getX() & 15; int lx = pos.getX() & 15;
int ly = pos.getY(); int ly = pos.getY();
int lz = pos.getZ() & 15; int lz = pos.getZ() & 15;
@ -305,13 +352,16 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
if (toRemove == null) { if (toRemove == null) {
toRemove = new HashMap<>(); toRemove = new HashMap<>();
} }
if (copy != null) {
storeTile(tile.getValue(), tile.getKey());
}
toRemove.put(tile.getKey(), tile.getValue()); toRemove.put(tile.getKey(), tile.getValue());
} }
} }
if (toRemove != null) { if (toRemove != null) {
for (Map.Entry<BlockPosition, TileEntity> entry : toRemove.entrySet()) { for (Map.Entry<net.minecraft.server.v1_10_R1.BlockPosition, net.minecraft.server.v1_10_R1.TileEntity> entry : toRemove.entrySet()) {
BlockPosition bp = entry.getKey(); net.minecraft.server.v1_10_R1.BlockPosition bp = entry.getKey();
TileEntity tile = entry.getValue(); net.minecraft.server.v1_10_R1.TileEntity tile = entry.getValue();
tiles.remove(bp); tiles.remove(bp);
tile.y(); tile.y();
nmsWorld.s(bp); nmsWorld.s(bp);
@ -325,12 +375,15 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
if (count == 0) { if (count == 0) {
continue; continue;
} }
int countAir = this.getAir(j);
final char[] array = this.getIdArray(j); final char[] array = this.getIdArray(j);
if (array == null) { if (array == null) {
continue; continue;
} }
int countAir = this.getAir(j); net.minecraft.server.v1_10_R1.ChunkSection section = sections[j];
ChunkSection section = sections[j]; if (copy != null) {
copy.storeSection(section, j);
}
if (section == null) { if (section == null) {
if (count == countAir) { if (count == countAir) {
continue; continue;
@ -342,8 +395,8 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
continue; continue;
} else { } else {
sections[j] = getParent().newChunkSection(j << 4, flag, array); sections[j] = getParent().newChunkSection(j << 4, flag, array);
continue;
} }
continue;
} else if (count >= 4096) { } else if (count >= 4096) {
if (countAir >= 4096) { if (countAir >= 4096) {
sections[j] = null; sections[j] = null;
@ -355,13 +408,13 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
continue; continue;
} else { } else {
sections[j] = getParent().newChunkSection(j << 4, flag, array); sections[j] = getParent().newChunkSection(j << 4, flag, array);
continue;
} }
continue;
} }
int by = j << 4; int by = j << 4;
DataPaletteBlock nibble = section.getBlocks(); net.minecraft.server.v1_10_R1.DataPaletteBlock nibble = section.getBlocks();
int nonEmptyBlockCount = 0; int nonEmptyBlockCount = 0;
IBlockData existing; net.minecraft.server.v1_10_R1.IBlockData existing;
for (int y = 0; y < 16; y++) { for (int y = 0; y < 16; y++) {
short[][] i1 = FaweCache.CACHE_J[y]; short[][] i1 = FaweCache.CACHE_J[y];
for (int z = 0; z < 16; z++) { for (int z = 0; z < 16; z++) {
@ -399,6 +452,9 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
} }
// Set biomes // Set biomes
if (this.biomes != null) { if (this.biomes != null) {
if (copy != null) {
copy.storeBiomes(nmsChunk.getBiomeIndex());
}
byte[] currentBiomes = nmsChunk.getBiomeIndex(); byte[] currentBiomes = nmsChunk.getBiomeIndex();
for (int i = 0 ; i < this.biomes.length; i++) { for (int i = 0 ; i < this.biomes.length; i++) {
if (this.biomes[i] != 0) { if (this.biomes[i] != 0) {
@ -408,20 +464,23 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
} }
// Set tiles // Set tiles
Map<Short, CompoundTag> tilesToSpawn = this.getTiles(); Map<Short, CompoundTag> tilesToSpawn = this.getTiles();
for (Map.Entry<Short, CompoundTag> entry : tilesToSpawn.entrySet()) { for (Map.Entry<Short, CompoundTag> entry : tilesToSpawn.entrySet()) {
CompoundTag nativeTag = entry.getValue(); CompoundTag nativeTag = entry.getValue();
short blockHash = entry.getKey(); short blockHash = entry.getKey();
int x = (blockHash >> 12 & 0xF) + bx; int x = (blockHash >> 12 & 0xF) + bx;
int y = (blockHash & 0xFF); int y = (blockHash & 0xFF);
int z = (blockHash >> 8 & 0xF) + bz; int z = (blockHash >> 8 & 0xF) + bz;
BlockPosition pos = new BlockPosition(x, y, z); // Set pos net.minecraft.server.v1_10_R1.BlockPosition pos = new net.minecraft.server.v1_10_R1.BlockPosition(x, y, z); // Set pos
TileEntity tileEntity = nmsWorld.getTileEntity(pos); net.minecraft.server.v1_10_R1.TileEntity tileEntity = nmsWorld.getTileEntity(pos);
if (tileEntity != null) { if (tileEntity != null) {
NBTTagCompound tag = (NBTTagCompound) BukkitQueue_1_10.methodFromNative.invoke(BukkitQueue_1_10.adapter, nativeTag); net.minecraft.server.v1_10_R1.NBTTagCompound tag = (net.minecraft.server.v1_10_R1.NBTTagCompound) com.boydti.fawe.bukkit.v1_10.BukkitQueue_1_10.methodFromNative.invoke(com.boydti.fawe.bukkit.v1_10.BukkitQueue_1_10.adapter, nativeTag);
tileEntity.a(tag); // ReadTagIntoTile tileEntity.a(tag); // ReadTagIntoTile
} }
} }
// Change task
if (copy != null) {
getParent().getChangeTask().run(copy, this);
}
} catch (Throwable e) { } catch (Throwable e) {
MainUtil.handleError(e); MainUtil.handleError(e);
} }

View File

@ -206,6 +206,12 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
getChunk().load(true); getChunk().load(true);
} }
private void removeEntity(Entity entity) {
entity.b(false);
entity.die();
entity.valid = false;
}
@Override @Override
public FaweChunk call() { public FaweChunk call() {
try { try {
@ -227,18 +233,18 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
// Remove entities // Remove entities
HashSet<UUID> entsToRemove = this.getEntityRemoves(); HashSet<UUID> entsToRemove = this.getEntityRemoves();
if (!entsToRemove.isEmpty()) { if (!entsToRemove.isEmpty()) {
synchronized (BukkitQueue_0.class) { for (int i = 0; i < entities.length; i++) {
for (int i = 0; i < entities.length; i++) { Collection<Entity> ents = entities[i];
Collection<Entity> ents = entities[i]; if (!ents.isEmpty()) {
if (ents.isEmpty()) { Iterator<Entity> iter = ents.iterator();
Entity[] entsArr = ents.toArray(new Entity[ents.size()]); while (iter.hasNext()) {
for (Entity entity : entsArr) { Entity entity = iter.next();
if (entsToRemove.contains(entity.getUniqueID())) { if (entsToRemove.contains(entity.getUniqueID())) {
if (copy != null) { if (copy != null) {
copy.storeEntity(entity); copy.storeEntity(entity);
}
nmsWorld.removeEntity(entity);
} }
removeEntity(entity);
iter.remove();
} }
} }
} }
@ -264,23 +270,23 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
Collection<Entity> ents = entities[i]; Collection<Entity> ents = entities[i];
if (!ents.isEmpty()) { if (!ents.isEmpty()) {
char[] array = this.getIdArray(i); char[] array = this.getIdArray(i);
if (array == null || ents == null || ents.isEmpty()) continue; if (array == null) continue;
Entity[] entsArr = ents.toArray(new Entity[ents.size()]); Iterator<Entity> iter = ents.iterator();
synchronized (BukkitQueue_0.class) { while (iter.hasNext()) {
for (Entity entity : entsArr) { Entity entity = iter.next();
if (entity instanceof EntityPlayer) { if (entity instanceof EntityPlayer) {
continue; continue;
} }
int x = ((int) Math.round(entity.locX) & 15); int x = ((int) Math.round(entity.locX) & 15);
int z = ((int) Math.round(entity.locZ) & 15); int z = ((int) Math.round(entity.locZ) & 15);
int y = (int) Math.round(entity.locY); int y = (int) Math.round(entity.locY);
if (y < 0 || y > 255) continue; if (y < 0 || y > 255) continue;
if (array[FaweCache.CACHE_J[y][z][x]] != 0) { if (array[FaweCache.CACHE_J[y][z][x]] != 0) {
if (copy != null) { if (copy != null) {
copy.storeEntity(entity); copy.storeEntity(entity);
}
nmsWorld.removeEntity(entity);
} }
iter.remove();
removeEntity(entity);
} }
} }
} }