Fix packet sending for null chunk sections
This commit is contained in:
parent
362067f90d
commit
850bb533cb
@ -166,6 +166,9 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
|||||||
return world.isChunkLoaded(x, z);
|
return world.isChunkLoaded(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshChunk(FaweChunk fs) {}
|
public void refreshChunk(FaweChunk fs) {}
|
||||||
|
|
||||||
|
@ -81,9 +81,11 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
|||||||
protected static Field fieldGenLayer2;
|
protected static Field fieldGenLayer2;
|
||||||
protected static MutableGenLayer genLayer;
|
protected static MutableGenLayer genLayer;
|
||||||
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE];
|
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE];
|
||||||
|
protected static ChunkSection emptySection;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
|
emptySection = new ChunkSection(0, false);
|
||||||
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||||
@ -346,11 +348,25 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
|||||||
return MathMan.pair16(ibd.c(), ibd.d());
|
return MathMan.pair16(ibd.c(), ibd.d());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
|
if (!isChunkLoaded(x, z)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendChunk(getWorld().getChunkAt(x, z), bitMask);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshChunk(FaweChunk fc) {
|
public void refreshChunk(FaweChunk fc) {
|
||||||
BukkitChunk_1_10 fs = (BukkitChunk_1_10) fc;
|
BukkitChunk_1_10 fs = (BukkitChunk_1_10) fc;
|
||||||
ensureChunkLoaded(fc.getX(), fc.getZ());
|
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Chunk chunk = fs.getChunk();
|
Chunk chunk = fs.getChunk();
|
||||||
|
sendChunk(chunk, fs.getBitMask());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendChunk(Chunk chunk, int mask) {
|
||||||
if (!chunk.isLoaded()) {
|
if (!chunk.isLoaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -365,7 +381,14 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Send chunks
|
// Send chunks
|
||||||
int mask = fc.getBitMask();
|
boolean empty = false;
|
||||||
|
ChunkSection[] sections = nmsChunk.getSections();
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == null) {
|
||||||
|
sections[i] = emptySection;
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65280);
|
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65280);
|
||||||
for (EntityPlayer player : playerChunk.c) {
|
for (EntityPlayer player : playerChunk.c) {
|
||||||
@ -377,6 +400,13 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
|||||||
for (EntityPlayer player : playerChunk.c) {
|
for (EntityPlayer player : playerChunk.c) {
|
||||||
player.playerConnection.sendPacket(packet);
|
player.playerConnection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
|
if (empty) {
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == emptySection) {
|
||||||
|
sections[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasEntities(net.minecraft.server.v1_10_R1.Chunk nmsChunk) {
|
public boolean hasEntities(net.minecraft.server.v1_10_R1.Chunk nmsChunk) {
|
||||||
|
@ -42,10 +42,10 @@ public class BukkitChunk_1_11_Copy extends BukkitChunk_1_11 {
|
|||||||
|
|
||||||
this.ids[i] = combined = new char[4096];
|
this.ids[i] = combined = new char[4096];
|
||||||
for (int j = 0, k = 0; j < 2048; j++, k += 2) {
|
for (int j = 0, k = 0; j < 2048; j++, k += 2) {
|
||||||
combined[k] = (char) ((idsBytesArray[j] << 4) + (datasBytesArray[j] & 15));
|
combined[k] = (char) ((idsBytesArray[k] << 4) + (datasBytesArray[j] & 15));
|
||||||
}
|
}
|
||||||
for (int j = 0, k = 1; j < 2048; j++, k += 2) {
|
for (int j = 0, k = 1; j < 2048; j++, k += 2) {
|
||||||
combined[k] = (char) ((idsBytesArray[j] << 4) + (datasBytesArray[j] >> 4));
|
combined[k] = (char) ((idsBytesArray[k] << 4) + (datasBytesArray[j] >> 4));
|
||||||
}
|
}
|
||||||
return combined;
|
return combined;
|
||||||
}
|
}
|
||||||
|
@ -86,12 +86,13 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
|||||||
protected static Field fieldGenLayer1;
|
protected static Field fieldGenLayer1;
|
||||||
protected static Field fieldGenLayer2;
|
protected static Field fieldGenLayer2;
|
||||||
protected static MutableGenLayer genLayer;
|
protected static MutableGenLayer genLayer;
|
||||||
|
protected static ChunkSection emptySection;
|
||||||
|
|
||||||
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE];
|
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE];
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
|
emptySection = new ChunkSection(0, true);
|
||||||
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||||
@ -354,11 +355,25 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
|||||||
return MathMan.pair16(ibd.c(), ibd.d());
|
return MathMan.pair16(ibd.c(), ibd.d());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
|
if (!isChunkLoaded(x, z)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendChunk(getWorld().getChunkAt(x, z), bitMask);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshChunk(FaweChunk fc) {
|
public void refreshChunk(FaweChunk fc) {
|
||||||
BukkitChunk_1_11 fs = (BukkitChunk_1_11) fc;
|
BukkitChunk_1_11 fs = (BukkitChunk_1_11) fc;
|
||||||
ensureChunkLoaded(fc.getX(), fc.getZ());
|
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Chunk chunk = fs.getChunk();
|
Chunk chunk = fs.getChunk();
|
||||||
|
sendChunk(chunk, fs.getBitMask());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendChunk(Chunk chunk, int mask) {
|
||||||
if (!chunk.isLoaded()) {
|
if (!chunk.isLoaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -373,7 +388,14 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Send chunks
|
// Send chunks
|
||||||
int mask = fc.getBitMask();
|
boolean empty = false;
|
||||||
|
ChunkSection[] sections = nmsChunk.getSections();
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == null) {
|
||||||
|
sections[i] = emptySection;
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mask == 0 || mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
if (mask == 0 || mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65280);
|
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65280);
|
||||||
for (EntityPlayer player : playerChunk.c) {
|
for (EntityPlayer player : playerChunk.c) {
|
||||||
@ -385,6 +407,13 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
|||||||
for (EntityPlayer player : playerChunk.c) {
|
for (EntityPlayer player : playerChunk.c) {
|
||||||
player.playerConnection.sendPacket(packet);
|
player.playerConnection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
|
if (empty) {
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == emptySection) {
|
||||||
|
sections[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasEntities(net.minecraft.server.v1_11_R1.Chunk nmsChunk) {
|
public boolean hasEntities(net.minecraft.server.v1_11_R1.Chunk nmsChunk) {
|
||||||
@ -504,60 +533,22 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ThreadLocal<byte[]> ID_CACHE = new ThreadLocal<byte[]>() {
|
|
||||||
@Override
|
|
||||||
protected byte[] initialValue() {
|
|
||||||
return new byte[4096];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static ThreadLocal<NibbleArray> DATA_CACHE = new ThreadLocal<NibbleArray>() {
|
|
||||||
@Override
|
|
||||||
protected NibbleArray initialValue() {
|
|
||||||
return new NibbleArray();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BukkitChunk_1_11 getPrevious(CharFaweChunk fs, ChunkSection[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
public BukkitChunk_1_11 getPrevious(CharFaweChunk fs, ChunkSection[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||||
Map<BlockPosition, TileEntity> tiles = (Map<BlockPosition, TileEntity>) tilesGeneric;
|
Map<BlockPosition, TileEntity> tiles = (Map<BlockPosition, TileEntity>) tilesGeneric;
|
||||||
Collection<Entity>[] entities = (Collection<Entity>[]) entitiesGeneric;
|
Collection<Entity>[] entities = (Collection<Entity>[]) entitiesGeneric;
|
||||||
// Copy blocks
|
// Copy blocks
|
||||||
// BukkitChunk_1_11_Copy previous = new BukkitChunk_1_11_Copy(this, fs.getX(), fs.getZ());
|
BukkitChunk_1_11_Copy previous = new BukkitChunk_1_11_Copy(this, fs.getX(), fs.getZ());
|
||||||
BukkitChunk_1_11 previous = getFaweChunk(fs.getX(), fs.getZ());
|
|
||||||
char[][] idPrevious = previous.getCombinedIdArrays();
|
|
||||||
for (int layer = 0; layer < sections.length; layer++) {
|
for (int layer = 0; layer < sections.length; layer++) {
|
||||||
if (fs.getCount(layer) != 0 || all) {
|
if (fs.getCount(layer) != 0 || all) {
|
||||||
ChunkSection section = sections[layer];
|
ChunkSection section = sections[layer];
|
||||||
if (section != null) {
|
if (section != null) {
|
||||||
// DataPaletteBlock blocks = section.getBlocks();
|
|
||||||
// byte[] ids = ID_CACHE.get();
|
|
||||||
// NibbleArray data = DATA_CACHE.get();
|
|
||||||
// blocks.exportData(ids, data);
|
|
||||||
// previous.set(layer, ids, data.asBytes());
|
|
||||||
// short solid = (short) fieldNonEmptyBlockCount.getInt(section);
|
|
||||||
// previous.count[layer] = solid;
|
|
||||||
// previous.air[layer] = (short) (4096 - solid);
|
|
||||||
short solid = 0;
|
|
||||||
char[] previousLayer = idPrevious[layer] = new char[4096];
|
|
||||||
DataPaletteBlock blocks = section.getBlocks();
|
DataPaletteBlock blocks = section.getBlocks();
|
||||||
for (int j = 0; j < 4096; j++) {
|
byte[] ids = new byte[4096];
|
||||||
int x = FaweCache.CACHE_X[0][j];
|
NibbleArray data = new NibbleArray();
|
||||||
int y = FaweCache.CACHE_Y[0][j];
|
blocks.exportData(ids, data);
|
||||||
int z = FaweCache.CACHE_Z[0][j];
|
previous.set(layer, ids, data.asBytes());
|
||||||
IBlockData ibd = blocks.a(x, y, z);
|
short solid = (short) fieldNonEmptyBlockCount.getInt(section);
|
||||||
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.count[layer] = solid;
|
||||||
previous.air[layer] = (short) (4096 - solid);
|
previous.air[layer] = (short) (4096 - solid);
|
||||||
}
|
}
|
||||||
|
@ -72,9 +72,12 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
|||||||
protected static Field fieldGenLayer1;
|
protected static Field fieldGenLayer1;
|
||||||
protected static Field fieldGenLayer2;
|
protected static Field fieldGenLayer2;
|
||||||
protected static com.boydti.fawe.bukkit.v1_7.MutableGenLayer genLayer;
|
protected static com.boydti.fawe.bukkit.v1_7.MutableGenLayer genLayer;
|
||||||
|
protected static ChunkSection emptySection;
|
||||||
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
|
emptySection = new ChunkSection(0, false);
|
||||||
fieldData = ChunkSection.class.getDeclaredField("blockData");
|
fieldData = ChunkSection.class.getDeclaredField("blockData");
|
||||||
fieldData.setAccessible(true);
|
fieldData.setAccessible(true);
|
||||||
fieldIds = ChunkSection.class.getDeclaredField("blockIds");
|
fieldIds = ChunkSection.class.getDeclaredField("blockIds");
|
||||||
@ -326,11 +329,25 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
|||||||
return (int) fieldNonEmptyBlockCount.get(section);
|
return (int) fieldNonEmptyBlockCount.get(section);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
|
if (!isChunkLoaded(x, z)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendChunk(getWorld().getChunkAt(x, z), bitMask);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshChunk(FaweChunk fc) {
|
public void refreshChunk(FaweChunk fc) {
|
||||||
BukkitChunk_1_7 fs = (BukkitChunk_1_7) fc;
|
BukkitChunk_1_7 fs = (BukkitChunk_1_7) fc;
|
||||||
ensureChunkLoaded(fc.getX(), fc.getZ());
|
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Chunk chunk = fs.getChunk();
|
Chunk chunk = fs.getChunk();
|
||||||
|
sendChunk(chunk, fs.getBitMask());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendChunk(Chunk chunk, int mask) {
|
||||||
if (!chunk.isLoaded()) {
|
if (!chunk.isLoaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -360,10 +377,17 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Send chunks
|
// Send chunks
|
||||||
|
boolean empty = false;
|
||||||
|
ChunkSection[] sections = nmsChunk.getSections();
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == null) {
|
||||||
|
sections[i] = emptySection;
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
int version = -1;
|
int version = -1;
|
||||||
PacketPlayOutMapChunk packet = null;
|
PacketPlayOutMapChunk packet = null;
|
||||||
Map<Integer, PacketPlayOutMapChunk> packets = null;
|
Map<Integer, PacketPlayOutMapChunk> packets = null;
|
||||||
int mask = fc.getBitMask();
|
|
||||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||||
for (EntityPlayer player : players) {
|
for (EntityPlayer player : players) {
|
||||||
int currentVersion = player.playerConnection.networkManager.getVersion();
|
int currentVersion = player.playerConnection.networkManager.getVersion();
|
||||||
@ -404,6 +428,13 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
|||||||
}
|
}
|
||||||
player.playerConnection.sendPacket(packet);
|
player.playerConnection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
|
if (empty) {
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == emptySection) {
|
||||||
|
sections[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
|
@ -73,9 +73,11 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
|||||||
protected static Field fieldGenLayer1;
|
protected static Field fieldGenLayer1;
|
||||||
protected static Field fieldGenLayer2;
|
protected static Field fieldGenLayer2;
|
||||||
protected static com.boydti.fawe.bukkit.v1_8.MutableGenLayer genLayer;
|
protected static com.boydti.fawe.bukkit.v1_8.MutableGenLayer genLayer;
|
||||||
|
protected static ChunkSection emptySection;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
|
emptySection = new ChunkSection(0, false);
|
||||||
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||||
@ -329,11 +331,25 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
|||||||
return (int) fieldNonEmptyBlockCount.get(section);
|
return (int) fieldNonEmptyBlockCount.get(section);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
|
if (!isChunkLoaded(x, z)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendChunk(getWorld().getChunkAt(x, z), bitMask);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshChunk(FaweChunk fc) {
|
public void refreshChunk(FaweChunk fc) {
|
||||||
BukkitChunk_1_8 fs = (BukkitChunk_1_8) fc;
|
BukkitChunk_1_8 fs = (BukkitChunk_1_8) fc;
|
||||||
ensureChunkLoaded(fc.getX(), fc.getZ());
|
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Chunk chunk = fs.getChunk();
|
Chunk chunk = fs.getChunk();
|
||||||
|
sendChunk(chunk, fs.getBitMask());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendChunk(Chunk chunk, int mask) {
|
||||||
if (!chunk.isLoaded()) {
|
if (!chunk.isLoaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -356,8 +372,15 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
|||||||
if (players.isEmpty()) {
|
if (players.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
boolean empty = false;
|
||||||
|
ChunkSection[] sections = nmsChunk.getSections();
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == null) {
|
||||||
|
sections[i] = emptySection;
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Send chunks
|
// Send chunks
|
||||||
int mask = fc.getBitMask();
|
|
||||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, 65280);
|
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, 65280);
|
||||||
for (EntityPlayer player : players) {
|
for (EntityPlayer player : players) {
|
||||||
@ -377,6 +400,13 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
|||||||
player.playerConnection.sendPacket(tilePacket);
|
player.playerConnection.sendPacket(tilePacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (empty) {
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == emptySection) {
|
||||||
|
sections[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
|
@ -77,9 +77,11 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
|||||||
protected static Field fieldGenLayer1;
|
protected static Field fieldGenLayer1;
|
||||||
protected static Field fieldGenLayer2;
|
protected static Field fieldGenLayer2;
|
||||||
protected static com.boydti.fawe.bukkit.v1_9.MutableGenLayer genLayer;
|
protected static com.boydti.fawe.bukkit.v1_9.MutableGenLayer genLayer;
|
||||||
|
protected static ChunkSection emptySection;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
|
emptySection = new ChunkSection(0, false);
|
||||||
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||||
@ -212,11 +214,25 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
|
if (!isChunkLoaded(x, z)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendChunk(getWorld().getChunkAt(x, z), bitMask);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshChunk(FaweChunk fc) {
|
public void refreshChunk(FaweChunk fc) {
|
||||||
BukkitChunk_1_9 fs = (BukkitChunk_1_9) fc;
|
BukkitChunk_1_9 fs = (BukkitChunk_1_9) fc;
|
||||||
ensureChunkLoaded(fc.getX(), fc.getZ());
|
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Chunk chunk = fs.getChunk();
|
Chunk chunk = fs.getChunk();
|
||||||
|
sendChunk(chunk, fs.getBitMask());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendChunk(Chunk chunk, int mask) {
|
||||||
if (!chunk.isLoaded()) {
|
if (!chunk.isLoaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -231,7 +247,14 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Send chunks
|
// Send chunks
|
||||||
int mask = fc.getBitMask();
|
boolean empty = false;
|
||||||
|
ChunkSection[] sections = nmsChunk.getSections();
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == null) {
|
||||||
|
sections[i] = emptySection;
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65280);
|
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65280);
|
||||||
for (EntityPlayer player : playerChunk.c) {
|
for (EntityPlayer player : playerChunk.c) {
|
||||||
@ -243,6 +266,13 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
|||||||
for (EntityPlayer player : playerChunk.c) {
|
for (EntityPlayer player : playerChunk.c) {
|
||||||
player.playerConnection.sendPacket(packet);
|
player.playerConnection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
|
if (empty) {
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == emptySection) {
|
||||||
|
sections[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasEntities(net.minecraft.server.v1_9_R2.Chunk nmsChunk) {
|
public boolean hasEntities(net.minecraft.server.v1_9_R2.Chunk nmsChunk) {
|
||||||
|
@ -11,11 +11,9 @@ import java.util.Arrays;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class NMSRelighter implements Relighter{
|
public class NMSRelighter implements Relighter{
|
||||||
@ -24,7 +22,7 @@ public class NMSRelighter implements Relighter{
|
|||||||
private final Map<Long, RelightSkyEntry> skyToRelight;
|
private final Map<Long, RelightSkyEntry> skyToRelight;
|
||||||
private final Map<Long, Map<Short, Object>> lightQueue;
|
private final Map<Long, Map<Short, Object>> lightQueue;
|
||||||
private final Object present = new Object();
|
private final Object present = new Object();
|
||||||
private final Set<Long> chunksToSend;
|
private final HashMap<Long, Integer> chunksToSend;
|
||||||
|
|
||||||
private final int maxY;
|
private final int maxY;
|
||||||
private volatile boolean relighting = false;
|
private volatile boolean relighting = false;
|
||||||
@ -37,7 +35,7 @@ public class NMSRelighter implements Relighter{
|
|||||||
this.queue = queue;
|
this.queue = queue;
|
||||||
this.skyToRelight = new ConcurrentHashMap<>();
|
this.skyToRelight = new ConcurrentHashMap<>();
|
||||||
this.lightQueue = new ConcurrentHashMap<>();
|
this.lightQueue = new ConcurrentHashMap<>();
|
||||||
chunksToSend = new LinkedHashSet<>();
|
chunksToSend = new HashMap<>();
|
||||||
this.maxY = queue.getMaxY();
|
this.maxY = queue.getMaxY();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,8 +64,10 @@ public class NMSRelighter implements Relighter{
|
|||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Map.Entry<Long, RelightSkyEntry> entry = iter.next();
|
Map.Entry<Long, RelightSkyEntry> entry = iter.next();
|
||||||
iter.remove();
|
iter.remove();
|
||||||
chunksToSend.add(entry.getKey());
|
|
||||||
RelightSkyEntry chunk = entry.getValue();
|
RelightSkyEntry chunk = entry.getValue();
|
||||||
|
long pair = entry.getKey();
|
||||||
|
Integer existing = chunksToSend.get(pair);
|
||||||
|
chunksToSend.put(pair, chunk.bitmask | (existing != null ? existing : 0));
|
||||||
queue.ensureChunkLoaded(chunk.x, chunk.z);
|
queue.ensureChunkLoaded(chunk.x, chunk.z);
|
||||||
Object sections = queue.getCachedSections(queue.getWorld(), chunk.x, chunk.z);
|
Object sections = queue.getCachedSections(queue.getWorld(), chunk.x, chunk.z);
|
||||||
queue.removeLighting(sections, FaweQueue.RelightMode.ALL, queue.hasSky());
|
queue.removeLighting(sections, FaweQueue.RelightMode.ALL, queue.hasSky());
|
||||||
@ -217,14 +217,15 @@ public class NMSRelighter implements Relighter{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void sendChunks() {
|
public void sendChunks() {
|
||||||
Iterator<Long> iter = chunksToSend.iterator();
|
Iterator<Map.Entry<Long, Integer>> iter = chunksToSend.entrySet().iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
long pair = iter.next();
|
Map.Entry<Long, Integer> entry = iter.next();
|
||||||
|
long pair = entry.getKey();
|
||||||
|
int bitMask = entry.getValue();
|
||||||
iter.remove();
|
iter.remove();
|
||||||
int x = MathMan.unpairIntX(pair);
|
int x = MathMan.unpairIntX(pair);
|
||||||
int z = MathMan.unpairIntY(pair);
|
int z = MathMan.unpairIntY(pair);
|
||||||
CharFaweChunk fc = (CharFaweChunk) queue.getFaweChunk(x, z);
|
queue.sendChunk(x, z, bitMask);
|
||||||
queue.sendChunk(fc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,7 +240,7 @@ public class NMSRelighter implements Relighter{
|
|||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Map.Entry<Long, RelightSkyEntry> entry = iter.next();
|
Map.Entry<Long, RelightSkyEntry> entry = iter.next();
|
||||||
iter.remove();
|
iter.remove();
|
||||||
chunksToSend.add(entry.getKey());
|
chunksToSend.put(entry.getKey(), entry.getValue().bitmask);
|
||||||
chunksList.add(entry.getValue());
|
chunksList.add(entry.getValue());
|
||||||
}
|
}
|
||||||
Collections.sort(chunksList);
|
Collections.sort(chunksList);
|
||||||
|
@ -238,6 +238,13 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
|
if (parentNMS != null) {
|
||||||
|
parentNMS.sendChunk(x, z, bitMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag getTileEntity(FaweChunk sections, int x, int y, int z) {
|
public CompoundTag getTileEntity(FaweChunk sections, int x, int y, int z) {
|
||||||
if (sections.getClass() == MCAChunk.class) {
|
if (sections.getClass() == MCAChunk.class) {
|
||||||
|
@ -283,6 +283,8 @@ public abstract class FaweQueue {
|
|||||||
|
|
||||||
public abstract void sendChunk(FaweChunk chunk);
|
public abstract void sendChunk(FaweChunk chunk);
|
||||||
|
|
||||||
|
public abstract void sendChunk(int x, int z, int bitMask);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called when the server is < 1% available memory
|
* This method is called when the server is < 1% available memory
|
||||||
*/
|
*/
|
||||||
|
@ -50,7 +50,7 @@ public abstract class FaweChangeSet implements ChangeSet {
|
|||||||
public FaweChangeSet(World world) {
|
public FaweChangeSet(World world) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.mainThread = Fawe.get().isMainThread();
|
this.mainThread = Fawe.get().isMainThread();
|
||||||
this.layers = this.world.getMaxY() >> 4;
|
this.layers = (this.world.getMaxY() + 1) >> 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
public World getWorld() {
|
public World getWorld() {
|
||||||
@ -221,41 +221,39 @@ public abstract class FaweChangeSet implements ChangeSet {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
// Block changes
|
// Block changes
|
||||||
{
|
// Current blocks
|
||||||
// Current blocks
|
|
||||||
// char[][] currentIds = next.getCombinedIdArrays();
|
// char[][] currentIds = next.getCombinedIdArrays();
|
||||||
// Previous blocks in modified sections (i.e. we skip sections that weren't modified)
|
// Previous blocks in modified sections (i.e. we skip sections that weren't modified)
|
||||||
// char[][] previousIds = previous.getCombinedIdArrays();
|
// char[][] previousIds = previous.getCombinedIdArrays();
|
||||||
for (int layer = 0; layer < layers; layer++) {
|
for (int layer = 0; layer < layers; layer++) {
|
||||||
char[] currentLayer = next.getIdArray(layer);
|
char[] currentLayer = next.getIdArray(layer);
|
||||||
char[] previousLayer = previous.getIdArray(layer);
|
char[] previousLayer = previous.getIdArray(layer);
|
||||||
if (currentLayer == null) {
|
if (currentLayer == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int startY = layer << 4;
|
int startY = layer << 4;
|
||||||
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];
|
||||||
int yy = y + startY;
|
int yy = y + startY;
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
int zz = z + bz;
|
int zz = z + bz;
|
||||||
short[] i2 = i1[z];
|
short[] i2 = i1[z];
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
int xx = x + bx;
|
int xx = x + bx;
|
||||||
int index = i2[x];
|
int index = i2[x];
|
||||||
int combinedIdCurrent = currentLayer[index];
|
int combinedIdCurrent = currentLayer[index];
|
||||||
switch (combinedIdCurrent) {
|
switch (combinedIdCurrent) {
|
||||||
case 0:
|
case 0:
|
||||||
continue;
|
continue;
|
||||||
case 1:
|
case 1:
|
||||||
combinedIdCurrent = 0;
|
combinedIdCurrent = 0;
|
||||||
default:
|
default:
|
||||||
char combinedIdPrevious = previousLayer != null ? previousLayer[index] : 0;
|
char combinedIdPrevious = previousLayer != null ? previousLayer[index] : 0;
|
||||||
if (combinedIdCurrent != combinedIdPrevious) {
|
if (combinedIdCurrent != combinedIdPrevious) {
|
||||||
synchronized (lockCombined) {
|
synchronized (lockCombined) {
|
||||||
add(xx, yy, zz, combinedIdPrevious, combinedIdCurrent);
|
add(xx, yy, zz, combinedIdPrevious, combinedIdCurrent);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,11 @@ public class DelegateFaweQueue extends FaweQueue {
|
|||||||
setWorld(parent.getWorldName());
|
setWorld(parent.getWorldName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
|
parent.sendChunk(x, z, bitMask);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWorldName() {
|
public String getWorldName() {
|
||||||
return parent.getWorldName();
|
return parent.getWorldName();
|
||||||
|
@ -61,9 +61,11 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
protected final static Method methodToNative;
|
protected final static Method methodToNative;
|
||||||
protected final static Field fieldTickingBlockCount;
|
protected final static Field fieldTickingBlockCount;
|
||||||
protected final static Field fieldNonEmptyBlockCount;
|
protected final static Field fieldNonEmptyBlockCount;
|
||||||
|
protected static ExtendedBlockStorage emptySection;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
|
emptySection = new ExtendedBlockStorage(0, false);
|
||||||
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
|
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
|
||||||
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
|
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
|
||||||
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
|
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
|
||||||
@ -354,11 +356,25 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
fieldSection.set(section, palette);
|
fieldSection.set(section, palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
|
if (!isChunkLoaded(x, z)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendChunk(getChunk(getImpWorld(), x, z), bitMask);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshChunk(FaweChunk fc) {
|
public void refreshChunk(FaweChunk fc) {
|
||||||
ForgeChunk_All fs = (ForgeChunk_All) fc;
|
ForgeChunk_All fs = (ForgeChunk_All) fc;
|
||||||
ensureChunkLoaded(fc.getX(), fc.getZ());
|
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||||
Chunk nmsChunk = fs.getChunk();
|
return;
|
||||||
|
}
|
||||||
|
Chunk chunk = fs.getChunk();
|
||||||
|
sendChunk(chunk, fs.getBitMask());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendChunk(Chunk nmsChunk, int mask) {
|
||||||
if (!nmsChunk.isLoaded()) {
|
if (!nmsChunk.isLoaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -377,7 +393,14 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
players.add(input);
|
players.add(input);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
int mask = fc.getBitMask();
|
boolean empty = false;
|
||||||
|
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == null) {
|
||||||
|
sections[i] = emptySection;
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||||
SPacketChunkData packet = new SPacketChunkData(nmsChunk, 65280);
|
SPacketChunkData packet = new SPacketChunkData(nmsChunk, 65280);
|
||||||
for (EntityPlayerMP player : players) {
|
for (EntityPlayerMP player : players) {
|
||||||
@ -389,6 +412,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
for (EntityPlayerMP player : players) {
|
for (EntityPlayerMP player : players) {
|
||||||
player.connection.sendPacket(packet);
|
player.connection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
|
if (empty) {
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == emptySection) {
|
||||||
|
sections[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
|
@ -75,11 +75,12 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
protected static Field fieldBiomes2;
|
protected static Field fieldBiomes2;
|
||||||
protected static Field fieldGenLayer1;
|
protected static Field fieldGenLayer1;
|
||||||
protected static Field fieldGenLayer2;
|
protected static Field fieldGenLayer2;
|
||||||
|
protected static ExtendedBlockStorage emptySection;
|
||||||
private static MutableGenLayer genLayer;
|
private static MutableGenLayer genLayer;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
|
emptySection = new ExtendedBlockStorage(0, false);
|
||||||
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
|
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
|
||||||
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
|
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
|
||||||
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
|
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
|
||||||
@ -431,11 +432,25 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
fieldSection.set(section, palette);
|
fieldSection.set(section, palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
|
if (!isChunkLoaded(x, z)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendChunk(getChunk(getImpWorld(), x, z), bitMask);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshChunk(FaweChunk fc) {
|
public void refreshChunk(FaweChunk fc) {
|
||||||
ForgeChunk_All fs = (ForgeChunk_All) fc;
|
ForgeChunk_All fs = (ForgeChunk_All) fc;
|
||||||
ensureChunkLoaded(fc.getX(), fc.getZ());
|
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||||
Chunk nmsChunk = fs.getChunk();
|
return;
|
||||||
|
}
|
||||||
|
Chunk chunk = fs.getChunk();
|
||||||
|
sendChunk(chunk, fs.getBitMask());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendChunk(Chunk nmsChunk, int mask) {
|
||||||
if (!nmsChunk.isLoaded()) {
|
if (!nmsChunk.isLoaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -454,7 +469,14 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
players.add(input);
|
players.add(input);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
int mask = fc.getBitMask();
|
boolean empty = false;
|
||||||
|
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == null) {
|
||||||
|
sections[i] = emptySection;
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||||
SPacketChunkData packet = new SPacketChunkData(nmsChunk, 65280);
|
SPacketChunkData packet = new SPacketChunkData(nmsChunk, 65280);
|
||||||
for (EntityPlayerMP player : players) {
|
for (EntityPlayerMP player : players) {
|
||||||
@ -466,6 +488,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
for (EntityPlayerMP player : players) {
|
for (EntityPlayerMP player : players) {
|
||||||
player.connection.sendPacket(packet);
|
player.connection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
|
if (empty) {
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == emptySection) {
|
||||||
|
sections[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
|
@ -56,30 +56,29 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
|
|
||||||
protected static Method methodFromNative;
|
protected static Method methodFromNative;
|
||||||
protected static Method methodToNative;
|
protected static Method methodToNative;
|
||||||
|
protected static ExtendedBlockStorage emptySection;
|
||||||
|
|
||||||
public ForgeQueue_All(com.sk89q.worldedit.world.World world) {
|
public ForgeQueue_All(com.sk89q.worldedit.world.World world) {
|
||||||
super(world);
|
super(world);
|
||||||
init();
|
getImpWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ForgeQueue_All(String world) {
|
public ForgeQueue_All(String world) {
|
||||||
super(world);
|
super(world);
|
||||||
init();
|
getImpWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init() {
|
static {
|
||||||
if (methodFromNative == null) {
|
try {
|
||||||
try {
|
emptySection = new ExtendedBlockStorage(0, false);
|
||||||
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
|
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
|
||||||
this.methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
|
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
|
||||||
this.methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
|
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
|
||||||
methodFromNative.setAccessible(true);
|
methodFromNative.setAccessible(true);
|
||||||
methodToNative.setAccessible(true);
|
methodToNative.setAccessible(true);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
getImpWorld();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -236,11 +235,25 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
|
if (!isChunkLoaded(x, z)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendChunk(getChunk(getImpWorld(), x, z), bitMask);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshChunk(FaweChunk fc) {
|
public void refreshChunk(FaweChunk fc) {
|
||||||
ForgeChunk_All fs = (ForgeChunk_All) fc;
|
ForgeChunk_All fs = (ForgeChunk_All) fc;
|
||||||
ensureChunkLoaded(fc.getX(), fc.getZ());
|
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||||
Chunk nmsChunk = fs.getChunk();
|
return;
|
||||||
|
}
|
||||||
|
Chunk chunk = fs.getChunk();
|
||||||
|
sendChunk(chunk, fs.getBitMask());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendChunk(Chunk nmsChunk, int mask) {
|
||||||
if (!nmsChunk.isChunkLoaded) {
|
if (!nmsChunk.isChunkLoaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -263,7 +276,14 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
if (players.size() == 0) {
|
if (players.size() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int mask = fc.getBitMask();
|
boolean empty = false;
|
||||||
|
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == null) {
|
||||||
|
sections[i] = emptySection;
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||||
S21PacketChunkData packet = new S21PacketChunkData(nmsChunk, false, 65280);
|
S21PacketChunkData packet = new S21PacketChunkData(nmsChunk, false, 65280);
|
||||||
for (EntityPlayerMP player : players) {
|
for (EntityPlayerMP player : players) {
|
||||||
@ -275,6 +295,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
for (EntityPlayerMP player : players) {
|
for (EntityPlayerMP player : players) {
|
||||||
player.playerNetServerHandler.sendPacket(packet);
|
player.playerNetServerHandler.sendPacket(packet);
|
||||||
}
|
}
|
||||||
|
if (empty) {
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == emptySection) {
|
||||||
|
sections[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
|
@ -55,9 +55,11 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
protected final static Method methodToNative;
|
protected final static Method methodToNative;
|
||||||
private static final Field fieldTickingBlockCount;
|
private static final Field fieldTickingBlockCount;
|
||||||
private static final Field fieldNonEmptyBlockCount;
|
private static final Field fieldNonEmptyBlockCount;
|
||||||
|
protected static ExtendedBlockStorage emptySection;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
|
emptySection = new ExtendedBlockStorage(0, false);
|
||||||
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
|
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
|
||||||
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
|
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
|
||||||
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
|
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
|
||||||
@ -295,11 +297,25 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
return previous;
|
return previous;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
|
if (!isChunkLoaded(x, z)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendChunk(getChunk(getImpWorld(), x, z), bitMask);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshChunk(FaweChunk fc) {
|
public void refreshChunk(FaweChunk fc) {
|
||||||
ForgeChunk_All fs = (ForgeChunk_All) fc;
|
ForgeChunk_All fs = (ForgeChunk_All) fc;
|
||||||
ensureChunkLoaded(fc.getX(), fc.getZ());
|
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||||
Chunk nmsChunk = fs.getChunk();
|
return;
|
||||||
|
}
|
||||||
|
Chunk chunk = fs.getChunk();
|
||||||
|
sendChunk(chunk, fs.getBitMask());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendChunk(Chunk nmsChunk, int mask) {
|
||||||
if (!nmsChunk.isLoaded()) {
|
if (!nmsChunk.isLoaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -322,7 +338,14 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
if (players.size() == 0) {
|
if (players.size() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int mask = fc.getBitMask();
|
boolean empty = false;
|
||||||
|
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == null) {
|
||||||
|
sections[i] = emptySection;
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||||
S21PacketChunkData packet = new S21PacketChunkData(nmsChunk, false, 65280);
|
S21PacketChunkData packet = new S21PacketChunkData(nmsChunk, false, 65280);
|
||||||
for (EntityPlayerMP player : players) {
|
for (EntityPlayerMP player : players) {
|
||||||
@ -334,6 +357,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
for (EntityPlayerMP player : players) {
|
for (EntityPlayerMP player : players) {
|
||||||
player.playerNetServerHandler.sendPacket(packet);
|
player.playerNetServerHandler.sendPacket(packet);
|
||||||
}
|
}
|
||||||
|
if (empty) {
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == emptySection) {
|
||||||
|
sections[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
|
@ -61,9 +61,11 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
protected final static Method methodToNative;
|
protected final static Method methodToNative;
|
||||||
protected final static Field fieldTickingBlockCount;
|
protected final static Field fieldTickingBlockCount;
|
||||||
protected final static Field fieldNonEmptyBlockCount;
|
protected final static Field fieldNonEmptyBlockCount;
|
||||||
|
protected static ExtendedBlockStorage emptySection;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
|
emptySection = new ExtendedBlockStorage(0, false);
|
||||||
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
|
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
|
||||||
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
|
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
|
||||||
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
|
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
|
||||||
@ -352,11 +354,25 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
fieldSection.set(section, palette);
|
fieldSection.set(section, palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
|
if (!isChunkLoaded(x, z)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendChunk(getChunk(getImpWorld(), x, z), bitMask);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshChunk(FaweChunk fc) {
|
public void refreshChunk(FaweChunk fc) {
|
||||||
ForgeChunk_All fs = (ForgeChunk_All) fc;
|
ForgeChunk_All fs = (ForgeChunk_All) fc;
|
||||||
ensureChunkLoaded(fc.getX(), fc.getZ());
|
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||||
Chunk nmsChunk = fs.getChunk();
|
return;
|
||||||
|
}
|
||||||
|
Chunk chunk = fs.getChunk();
|
||||||
|
sendChunk(chunk, fs.getBitMask());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendChunk(Chunk nmsChunk, int mask) {
|
||||||
if (!nmsChunk.isLoaded()) {
|
if (!nmsChunk.isLoaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -375,7 +391,14 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
players.add(input);
|
players.add(input);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
int mask = fc.getBitMask();
|
boolean empty = false;
|
||||||
|
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == null) {
|
||||||
|
sections[i] = emptySection;
|
||||||
|
empty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||||
SPacketChunkData packet = new SPacketChunkData(nmsChunk, 65280);
|
SPacketChunkData packet = new SPacketChunkData(nmsChunk, 65280);
|
||||||
for (EntityPlayerMP player : players) {
|
for (EntityPlayerMP player : players) {
|
||||||
@ -387,6 +410,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
|
|||||||
for (EntityPlayerMP player : players) {
|
for (EntityPlayerMP player : players) {
|
||||||
player.connection.sendPacket(packet);
|
player.connection.sendPacket(packet);
|
||||||
}
|
}
|
||||||
|
if (empty) {
|
||||||
|
for (int i = 0; i < sections.length; i++) {
|
||||||
|
if (sections[i] == emptySection) {
|
||||||
|
sections[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
|
@ -95,23 +95,26 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
|
|||||||
return MathMan.pair16(opacity, brightness);
|
return MathMan.pair16(opacity, brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void refreshChunk(FaweChunk fs) {
|
public void sendChunk(int x, int z, int bitMask) {
|
||||||
NukkitChunk fc = (NukkitChunk) fs;
|
|
||||||
Collection<Player> players = faweNukkit.getPlugin().getServer().getOnlinePlayers().values();
|
Collection<Player> players = faweNukkit.getPlugin().getServer().getOnlinePlayers().values();
|
||||||
int view = faweNukkit.getPlugin().getServer().getViewDistance();
|
int view = faweNukkit.getPlugin().getServer().getViewDistance();
|
||||||
for (Player player : players) {
|
for (Player player : players) {
|
||||||
Position pos = player.getPosition();
|
Position pos = player.getPosition();
|
||||||
int pcx = pos.getFloorX() >> 4;
|
int pcx = pos.getFloorX() >> 4;
|
||||||
int pcz = pos.getFloorZ() >> 4;
|
int pcz = pos.getFloorZ() >> 4;
|
||||||
if (Math.abs(pcx - fs.getX()) > view || Math.abs(pcz - fs.getZ()) > view) {
|
if (Math.abs(pcx - x) > view || Math.abs(pcz - z) > view) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
world.requestChunk(fs.getX(), fs.getZ(), player);
|
world.requestChunk(x, z, player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void refreshChunk(FaweChunk fs) {
|
||||||
|
sendChunk(fs.getX(), fs.getZ(), fs.getBitMask());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharFaweChunk getPrevious(CharFaweChunk fs, BaseFullChunk sections, Map<?, ?> tiles, Collection<?>[] entities, Set<UUID> createdEntities, boolean all) throws Exception {
|
public CharFaweChunk getPrevious(CharFaweChunk fs, BaseFullChunk sections, Map<?, ?> tiles, Collection<?>[] entities, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||||
return fs;
|
return fs;
|
||||||
|
Loading…
Reference in New Issue
Block a user