Fix packet sending for null chunk sections

This commit is contained in:
Jesse Boyd 2016-12-29 11:53:07 +11:00
parent 362067f90d
commit 850bb533cb
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
18 changed files with 412 additions and 135 deletions

View File

@ -166,6 +166,9 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
return world.isChunkLoaded(x, z);
}
@Override
public void sendChunk(int x, int z, int bitMask) {}
@Override
public void refreshChunk(FaweChunk fs) {}

View File

@ -81,9 +81,11 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
protected static Field fieldGenLayer2;
protected static MutableGenLayer genLayer;
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE];
protected static ChunkSection emptySection;
static {
try {
emptySection = new ChunkSection(0, false);
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
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());
}
@Override
public void sendChunk(int x, int z, int bitMask) {
if (!isChunkLoaded(x, z)) {
return;
}
sendChunk(getWorld().getChunkAt(x, z), bitMask);
}
@Override
public void refreshChunk(FaweChunk 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();
sendChunk(chunk, fs.getBitMask());
}
public void sendChunk(Chunk chunk, int mask) {
if (!chunk.isLoaded()) {
return;
}
@ -365,7 +381,14 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
return;
}
// 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)) {
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65280);
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) {
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) {

View File

@ -42,10 +42,10 @@ public class BukkitChunk_1_11_Copy extends BukkitChunk_1_11 {
this.ids[i] = combined = new char[4096];
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) {
combined[k] = (char) ((idsBytesArray[j] << 4) + (datasBytesArray[j] >> 4));
combined[k] = (char) ((idsBytesArray[k] << 4) + (datasBytesArray[j] >> 4));
}
return combined;
}

View File

@ -86,12 +86,13 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
protected static Field fieldGenLayer1;
protected static Field fieldGenLayer2;
protected static MutableGenLayer genLayer;
protected static ChunkSection emptySection;
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE];
static {
try {
emptySection = new ChunkSection(0, true);
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
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());
}
@Override
public void sendChunk(int x, int z, int bitMask) {
if (!isChunkLoaded(x, z)) {
return;
}
sendChunk(getWorld().getChunkAt(x, z), bitMask);
}
@Override
public void refreshChunk(FaweChunk 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();
sendChunk(chunk, fs.getBitMask());
}
public void sendChunk(Chunk chunk, int mask) {
if (!chunk.isLoaded()) {
return;
}
@ -373,7 +388,14 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
return;
}
// 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)) {
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65280);
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) {
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) {
@ -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
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;
Collection<Entity>[] entities = (Collection<Entity>[]) entitiesGeneric;
// Copy blocks
// 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();
BukkitChunk_1_11_Copy previous = new BukkitChunk_1_11_Copy(this, fs.getX(), fs.getZ());
for (int layer = 0; layer < sections.length; layer++) {
if (fs.getCount(layer) != 0 || all) {
ChunkSection section = sections[layer];
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();
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;
}
byte[] ids = new byte[4096];
NibbleArray data = new NibbleArray();
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);
}

View File

@ -72,9 +72,12 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
protected static Field fieldGenLayer1;
protected static Field fieldGenLayer2;
protected static com.boydti.fawe.bukkit.v1_7.MutableGenLayer genLayer;
protected static ChunkSection emptySection;
static {
try {
emptySection = new ChunkSection(0, false);
fieldData = ChunkSection.class.getDeclaredField("blockData");
fieldData.setAccessible(true);
fieldIds = ChunkSection.class.getDeclaredField("blockIds");
@ -326,11 +329,25 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
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
public void refreshChunk(FaweChunk 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();
sendChunk(chunk, fs.getBitMask());
}
public void sendChunk(Chunk chunk, int mask) {
if (!chunk.isLoaded()) {
return;
}
@ -360,10 +377,17 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
return;
}
// 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;
PacketPlayOutMapChunk packet = null;
Map<Integer, PacketPlayOutMapChunk> packets = null;
int mask = fc.getBitMask();
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
for (EntityPlayer player : players) {
int currentVersion = player.playerConnection.networkManager.getVersion();
@ -404,6 +428,13 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
}
player.playerConnection.sendPacket(packet);
}
if (empty) {
for (int i = 0; i < sections.length; i++) {
if (sections[i] == emptySection) {
sections[i] = null;
}
}
}
} catch (Throwable e) {
MainUtil.handleError(e);
}

View File

@ -73,9 +73,11 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
protected static Field fieldGenLayer1;
protected static Field fieldGenLayer2;
protected static com.boydti.fawe.bukkit.v1_8.MutableGenLayer genLayer;
protected static ChunkSection emptySection;
static {
try {
emptySection = new ChunkSection(0, false);
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
@ -329,11 +331,25 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
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
public void refreshChunk(FaweChunk 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();
sendChunk(chunk, fs.getBitMask());
}
public void sendChunk(Chunk chunk, int mask) {
if (!chunk.isLoaded()) {
return;
}
@ -356,8 +372,15 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
if (players.isEmpty()) {
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
int mask = fc.getBitMask();
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, false, 65280);
for (EntityPlayer player : players) {
@ -377,6 +400,13 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
player.playerConnection.sendPacket(tilePacket);
}
}
if (empty) {
for (int i = 0; i < sections.length; i++) {
if (sections[i] == emptySection) {
sections[i] = null;
}
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {

View File

@ -77,9 +77,11 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
protected static Field fieldGenLayer1;
protected static Field fieldGenLayer2;
protected static com.boydti.fawe.bukkit.v1_9.MutableGenLayer genLayer;
protected static ChunkSection emptySection;
static {
try {
emptySection = new ChunkSection(0, false);
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
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
public void refreshChunk(FaweChunk 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();
sendChunk(chunk, fs.getBitMask());
}
public void sendChunk(Chunk chunk, int mask) {
if (!chunk.isLoaded()) {
return;
}
@ -231,7 +247,14 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
return;
}
// 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)) {
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65280);
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) {
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) {

View File

@ -11,11 +11,9 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class NMSRelighter implements Relighter{
@ -24,7 +22,7 @@ public class NMSRelighter implements Relighter{
private final Map<Long, RelightSkyEntry> skyToRelight;
private final Map<Long, Map<Short, Object>> lightQueue;
private final Object present = new Object();
private final Set<Long> chunksToSend;
private final HashMap<Long, Integer> chunksToSend;
private final int maxY;
private volatile boolean relighting = false;
@ -37,7 +35,7 @@ public class NMSRelighter implements Relighter{
this.queue = queue;
this.skyToRelight = new ConcurrentHashMap<>();
this.lightQueue = new ConcurrentHashMap<>();
chunksToSend = new LinkedHashSet<>();
chunksToSend = new HashMap<>();
this.maxY = queue.getMaxY();
}
@ -66,8 +64,10 @@ public class NMSRelighter implements Relighter{
while (iter.hasNext()) {
Map.Entry<Long, RelightSkyEntry> entry = iter.next();
iter.remove();
chunksToSend.add(entry.getKey());
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);
Object sections = queue.getCachedSections(queue.getWorld(), chunk.x, chunk.z);
queue.removeLighting(sections, FaweQueue.RelightMode.ALL, queue.hasSky());
@ -217,14 +217,15 @@ public class NMSRelighter implements Relighter{
}
public void sendChunks() {
Iterator<Long> iter = chunksToSend.iterator();
Iterator<Map.Entry<Long, Integer>> iter = chunksToSend.entrySet().iterator();
while (iter.hasNext()) {
long pair = iter.next();
Map.Entry<Long, Integer> entry = iter.next();
long pair = entry.getKey();
int bitMask = entry.getValue();
iter.remove();
int x = MathMan.unpairIntX(pair);
int z = MathMan.unpairIntY(pair);
CharFaweChunk fc = (CharFaweChunk) queue.getFaweChunk(x, z);
queue.sendChunk(fc);
queue.sendChunk(x, z, bitMask);
}
}
@ -239,7 +240,7 @@ public class NMSRelighter implements Relighter{
while (iter.hasNext()) {
Map.Entry<Long, RelightSkyEntry> entry = iter.next();
iter.remove();
chunksToSend.add(entry.getKey());
chunksToSend.put(entry.getKey(), entry.getValue().bitmask);
chunksList.add(entry.getValue());
}
Collections.sort(chunksList);

View File

@ -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
public CompoundTag getTileEntity(FaweChunk sections, int x, int y, int z) {
if (sections.getClass() == MCAChunk.class) {

View File

@ -283,6 +283,8 @@ public abstract class FaweQueue {
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
*/

View File

@ -50,7 +50,7 @@ public abstract class FaweChangeSet implements ChangeSet {
public FaweChangeSet(World world) {
this.world = world;
this.mainThread = Fawe.get().isMainThread();
this.layers = this.world.getMaxY() >> 4;
this.layers = (this.world.getMaxY() + 1) >> 4;
}
public World getWorld() {
@ -221,41 +221,39 @@ public abstract class FaweChangeSet implements ChangeSet {
// TODO
}
// Block changes
{
// Current blocks
// Current blocks
// 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();
for (int layer = 0; layer < layers; layer++) {
char[] currentLayer = next.getIdArray(layer);
char[] previousLayer = previous.getIdArray(layer);
if (currentLayer == null) {
continue;
}
int startY = layer << 4;
for (int y = 0; y < 16; y++) {
short[][] i1 = FaweCache.CACHE_J[y];
int yy = y + startY;
for (int z = 0; z < 16; z++) {
int zz = z + bz;
short[] i2 = i1[z];
for (int x = 0; x < 16; x++) {
int xx = x + bx;
int index = i2[x];
int combinedIdCurrent = currentLayer[index];
switch (combinedIdCurrent) {
case 0:
continue;
case 1:
combinedIdCurrent = 0;
default:
char combinedIdPrevious = previousLayer != null ? previousLayer[index] : 0;
if (combinedIdCurrent != combinedIdPrevious) {
synchronized (lockCombined) {
add(xx, yy, zz, combinedIdPrevious, combinedIdCurrent);
}
for (int layer = 0; layer < layers; layer++) {
char[] currentLayer = next.getIdArray(layer);
char[] previousLayer = previous.getIdArray(layer);
if (currentLayer == null) {
continue;
}
int startY = layer << 4;
for (int y = 0; y < 16; y++) {
short[][] i1 = FaweCache.CACHE_J[y];
int yy = y + startY;
for (int z = 0; z < 16; z++) {
int zz = z + bz;
short[] i2 = i1[z];
for (int x = 0; x < 16; x++) {
int xx = x + bx;
int index = i2[x];
int combinedIdCurrent = currentLayer[index];
switch (combinedIdCurrent) {
case 0:
continue;
case 1:
combinedIdCurrent = 0;
default:
char combinedIdPrevious = previousLayer != null ? previousLayer[index] : 0;
if (combinedIdCurrent != combinedIdPrevious) {
synchronized (lockCombined) {
add(xx, yy, zz, combinedIdPrevious, combinedIdCurrent);
}
}
}
}
}
}

View File

@ -34,6 +34,11 @@ public class DelegateFaweQueue extends FaweQueue {
setWorld(parent.getWorldName());
}
@Override
public void sendChunk(int x, int z, int bitMask) {
parent.sendChunk(x, z, bitMask);
}
@Override
public String getWorldName() {
return parent.getWorldName();

View File

@ -61,9 +61,11 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
protected final static Method methodToNative;
protected final static Field fieldTickingBlockCount;
protected final static Field fieldNonEmptyBlockCount;
protected static ExtendedBlockStorage emptySection;
static {
try {
emptySection = new ExtendedBlockStorage(0, false);
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
@ -354,11 +356,25 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
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
public void refreshChunk(FaweChunk fc) {
ForgeChunk_All fs = (ForgeChunk_All) fc;
ensureChunkLoaded(fc.getX(), fc.getZ());
Chunk nmsChunk = fs.getChunk();
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
return;
}
Chunk chunk = fs.getChunk();
sendChunk(chunk, fs.getBitMask());
}
public void sendChunk(Chunk nmsChunk, int mask) {
if (!nmsChunk.isLoaded()) {
return;
}
@ -377,7 +393,14 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
players.add(input);
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)) {
SPacketChunkData packet = new SPacketChunkData(nmsChunk, 65280);
for (EntityPlayerMP player : players) {
@ -389,6 +412,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
for (EntityPlayerMP player : players) {
player.connection.sendPacket(packet);
}
if (empty) {
for (int i = 0; i < sections.length; i++) {
if (sections[i] == emptySection) {
sections[i] = null;
}
}
}
} catch (Throwable e) {
MainUtil.handleError(e);
}

View File

@ -75,11 +75,12 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
protected static Field fieldBiomes2;
protected static Field fieldGenLayer1;
protected static Field fieldGenLayer2;
protected static ExtendedBlockStorage emptySection;
private static MutableGenLayer genLayer;
static {
try {
emptySection = new ExtendedBlockStorage(0, false);
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
@ -431,11 +432,25 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
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
public void refreshChunk(FaweChunk fc) {
ForgeChunk_All fs = (ForgeChunk_All) fc;
ensureChunkLoaded(fc.getX(), fc.getZ());
Chunk nmsChunk = fs.getChunk();
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
return;
}
Chunk chunk = fs.getChunk();
sendChunk(chunk, fs.getBitMask());
}
public void sendChunk(Chunk nmsChunk, int mask) {
if (!nmsChunk.isLoaded()) {
return;
}
@ -454,7 +469,14 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
players.add(input);
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)) {
SPacketChunkData packet = new SPacketChunkData(nmsChunk, 65280);
for (EntityPlayerMP player : players) {
@ -466,6 +488,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
for (EntityPlayerMP player : players) {
player.connection.sendPacket(packet);
}
if (empty) {
for (int i = 0; i < sections.length; i++) {
if (sections[i] == emptySection) {
sections[i] = null;
}
}
}
} catch (Throwable e) {
MainUtil.handleError(e);
}

View File

@ -56,30 +56,29 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
protected static Method methodFromNative;
protected static Method methodToNative;
protected static ExtendedBlockStorage emptySection;
public ForgeQueue_All(com.sk89q.worldedit.world.World world) {
super(world);
init();
getImpWorld();
}
public ForgeQueue_All(String world) {
super(world);
init();
getImpWorld();
}
private void init() {
if (methodFromNative == null) {
try {
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
this.methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
this.methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
methodFromNative.setAccessible(true);
methodToNative.setAccessible(true);
} catch (Throwable e) {
throw new RuntimeException(e);
}
static {
try {
emptySection = new ExtendedBlockStorage(0, false);
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
methodFromNative.setAccessible(true);
methodToNative.setAccessible(true);
} catch (Throwable e) {
throw new RuntimeException(e);
}
getImpWorld();
}
@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
public void refreshChunk(FaweChunk fc) {
ForgeChunk_All fs = (ForgeChunk_All) fc;
ensureChunkLoaded(fc.getX(), fc.getZ());
Chunk nmsChunk = fs.getChunk();
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
return;
}
Chunk chunk = fs.getChunk();
sendChunk(chunk, fs.getBitMask());
}
public void sendChunk(Chunk nmsChunk, int mask) {
if (!nmsChunk.isChunkLoaded) {
return;
}
@ -263,7 +276,14 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
if (players.size() == 0) {
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)) {
S21PacketChunkData packet = new S21PacketChunkData(nmsChunk, false, 65280);
for (EntityPlayerMP player : players) {
@ -275,6 +295,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
for (EntityPlayerMP player : players) {
player.playerNetServerHandler.sendPacket(packet);
}
if (empty) {
for (int i = 0; i < sections.length; i++) {
if (sections[i] == emptySection) {
sections[i] = null;
}
}
}
} catch (Throwable e) {
MainUtil.handleError(e);
}

View File

@ -55,9 +55,11 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
protected final static Method methodToNative;
private static final Field fieldTickingBlockCount;
private static final Field fieldNonEmptyBlockCount;
protected static ExtendedBlockStorage emptySection;
static {
try {
emptySection = new ExtendedBlockStorage(0, false);
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
@ -295,11 +297,25 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
return previous;
}
@Override
public void sendChunk(int x, int z, int bitMask) {
if (!isChunkLoaded(x, z)) {
return;
}
sendChunk(getChunk(getImpWorld(), x, z), bitMask);
}
@Override
public void refreshChunk(FaweChunk fc) {
ForgeChunk_All fs = (ForgeChunk_All) fc;
ensureChunkLoaded(fc.getX(), fc.getZ());
Chunk nmsChunk = fs.getChunk();
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
return;
}
Chunk chunk = fs.getChunk();
sendChunk(chunk, fs.getBitMask());
}
public void sendChunk(Chunk nmsChunk, int mask) {
if (!nmsChunk.isLoaded()) {
return;
}
@ -322,7 +338,14 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
if (players.size() == 0) {
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)) {
S21PacketChunkData packet = new S21PacketChunkData(nmsChunk, false, 65280);
for (EntityPlayerMP player : players) {
@ -334,6 +357,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
for (EntityPlayerMP player : players) {
player.playerNetServerHandler.sendPacket(packet);
}
if (empty) {
for (int i = 0; i < sections.length; i++) {
if (sections[i] == emptySection) {
sections[i] = null;
}
}
}
} catch (Throwable e) {
MainUtil.handleError(e);
}

View File

@ -61,9 +61,11 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
protected final static Method methodToNative;
protected final static Field fieldTickingBlockCount;
protected final static Field fieldNonEmptyBlockCount;
protected static ExtendedBlockStorage emptySection;
static {
try {
emptySection = new ExtendedBlockStorage(0, false);
Class<?> converter = Class.forName("com.sk89q.worldedit.forge.NBTConverter");
methodFromNative = converter.getDeclaredMethod("toNative", Tag.class);
methodToNative = converter.getDeclaredMethod("fromNative", NBTBase.class);
@ -352,11 +354,25 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
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
public void refreshChunk(FaweChunk fc) {
ForgeChunk_All fs = (ForgeChunk_All) fc;
ensureChunkLoaded(fc.getX(), fc.getZ());
Chunk nmsChunk = fs.getChunk();
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
return;
}
Chunk chunk = fs.getChunk();
sendChunk(chunk, fs.getBitMask());
}
public void sendChunk(Chunk nmsChunk, int mask) {
if (!nmsChunk.isLoaded()) {
return;
}
@ -375,7 +391,14 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
players.add(input);
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)) {
SPacketChunkData packet = new SPacketChunkData(nmsChunk, 65280);
for (EntityPlayerMP player : players) {
@ -387,6 +410,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
for (EntityPlayerMP player : players) {
player.connection.sendPacket(packet);
}
if (empty) {
for (int i = 0; i < sections.length; i++) {
if (sections[i] == emptySection) {
sections[i] = null;
}
}
}
} catch (Throwable e) {
MainUtil.handleError(e);
}

View File

@ -95,23 +95,26 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
return MathMan.pair16(opacity, brightness);
}
@Override
public void refreshChunk(FaweChunk fs) {
NukkitChunk fc = (NukkitChunk) fs;
public void sendChunk(int x, int z, int bitMask) {
Collection<Player> players = faweNukkit.getPlugin().getServer().getOnlinePlayers().values();
int view = faweNukkit.getPlugin().getServer().getViewDistance();
for (Player player : players) {
Position pos = player.getPosition();
int pcx = pos.getFloorX() >> 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;
}
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
public CharFaweChunk getPrevious(CharFaweChunk fs, BaseFullChunk sections, Map<?, ?> tiles, Collection<?>[] entities, Set<UUID> createdEntities, boolean all) throws Exception {
return fs;