package net.minecraft.server; import com.google.common.collect.Lists; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import java.io.IOException; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; // Paper start import com.destroystokyo.paper.antixray.PacketPlayOutMapChunkInfo; // Anti-Xray // Paper end /** * Akarin Changes Note * 1) WrappedByteBuf -> ByteBuf (compatibility) */ public class PacketPlayOutMapChunk implements Packet { private int a; private int b; private int c; private ByteBuf d; // Akarin - byte[] -> ByteBuf private List e; private boolean f; private volatile boolean ready = false; // Paper - Async-Anti-Xray - Ready flag for the network manager // Paper start - Async-Anti-Xray - Set the ready flag to true public PacketPlayOutMapChunk() { this.ready = true; } // Paper end public PacketPlayOutMapChunk(Chunk chunk, int i) { PacketPlayOutMapChunkInfo packetPlayOutMapChunkInfo = chunk.world.chunkPacketBlockController.getPacketPlayOutMapChunkInfo(this, chunk, i); // Paper - Anti-Xray - Add chunk packet info this.a = chunk.locX; this.b = chunk.locZ; this.f = i == '\uffff'; boolean flag = chunk.getWorld().worldProvider.m(); this.d = allocateBuffer(this.a(chunk, flag, i)); // Akarin // Paper start - Anti-Xray - Add chunk packet info if (packetPlayOutMapChunkInfo != null) { packetPlayOutMapChunkInfo.setData(this.d); } // Paper end this.c = this.writeChunk(new PacketDataSerializer(this.d), chunk, flag, i, packetPlayOutMapChunkInfo); // Paper - Anti-Xray - Add chunk packet info // Akarin this.e = Lists.newArrayList(); Iterator iterator = chunk.getTileEntities().entrySet().iterator(); while (iterator.hasNext()) { Entry entry = (Entry) iterator.next(); BlockPosition blockposition = (BlockPosition) entry.getKey(); TileEntity tileentity = (TileEntity) entry.getValue(); int j = blockposition.getY() >> 4; if (this.e() || (i & 1 << j) != 0) { NBTTagCompound nbttagcompound = tileentity.d(); this.e.add(nbttagcompound); } } chunk.world.chunkPacketBlockController.modifyBlocks(this, packetPlayOutMapChunkInfo); // Paper - Anti-Xray - Modify blocks } // Paper start - Async-Anti-Xray - Getter and Setter for the ready flag public boolean isReady() { return this.ready; } public void setReady(boolean ready) { this.ready = ready; } // Paper end public void a(PacketDataSerializer packetdataserializer) throws IOException { this.a = packetdataserializer.readInt(); this.b = packetdataserializer.readInt(); this.f = packetdataserializer.readBoolean(); this.c = packetdataserializer.g(); int i = packetdataserializer.g(); if (i > 2097152) { throw new RuntimeException("Chunk Packet trying to allocate too much memory on read."); } else { this.d = Unpooled.buffer(i); // Akarin packetdataserializer.readBytes(this.d); int j = packetdataserializer.g(); this.e = Lists.newArrayList(); for (int k = 0; k < j; ++k) { this.e.add(packetdataserializer.j()); } } } public void b(PacketDataSerializer packetdataserializer) throws IOException { packetdataserializer.writeInt(this.a); packetdataserializer.writeInt(this.b); packetdataserializer.writeBoolean(this.f); packetdataserializer.d(this.c); packetdataserializer.d(this.d.capacity()); // Akarin packetdataserializer.writeBytes(this.d.array()); // Akarin packetdataserializer.d(this.e.size()); Iterator iterator = this.e.iterator(); while (iterator.hasNext()) { NBTTagCompound nbttagcompound = (NBTTagCompound) iterator.next(); packetdataserializer.a(nbttagcompound); } } public void a(PacketListenerPlayOut packetlistenerplayout) { packetlistenerplayout.a(this); } private ByteBuf g() { return allocateBuffer(-1); } // Akarin private ByteBuf allocateBuffer(int expectedCapacity) { // Akarin - added argument ByteBuf bytebuf = expectedCapacity == -1 ? Unpooled.buffer() : Unpooled.buffer(expectedCapacity); // Akarin bytebuf.writerIndex(0); return bytebuf; } // Paper start - Anti-Xray - Support default method public int writeChunk(PacketDataSerializer packetDataSerializer, Chunk chunk, boolean writeSkyLightArray, int chunkSectionSelector) { return this.a(packetDataSerializer, chunk, writeSkyLightArray, chunkSectionSelector); } // OBFHELPER public int a(PacketDataSerializer packetdataserializer, Chunk chunk, boolean flag, int i) { return this.a(packetdataserializer, chunk, flag, i, null); } // Paper end public int writeChunk(PacketDataSerializer packetDataSerializer, Chunk chunk, boolean writeSkyLightArray, int chunkSectionSelector, PacketPlayOutMapChunkInfo packetPlayOutMapChunkInfo) { return this.a(packetDataSerializer, chunk, writeSkyLightArray, chunkSectionSelector, packetPlayOutMapChunkInfo); } // Paper - Anti-Xray - OBFHELPER public int a(PacketDataSerializer packetdataserializer, Chunk chunk, boolean flag, int i, PacketPlayOutMapChunkInfo packetPlayOutMapChunkInfo) { // Paper - Anti-Xray - Add chunk packet info int j = 0; ChunkSection[] achunksection = chunk.getSections(); int k = 0; for (int l = achunksection.length; k < l; ++k) { ChunkSection chunksection = achunksection[k]; if (chunksection != Chunk.a && (!this.e() || !chunksection.a()) && (i & 1 << k) != 0) { j |= 1 << k; chunksection.getBlocks().writeBlocks(packetdataserializer, packetPlayOutMapChunkInfo, k); // Paper - Anti-Xray - Add chunk packet info packetdataserializer.writeBytes(chunksection.getEmittedLightArray().asBytes()); if (flag) { packetdataserializer.writeBytes(chunksection.getSkyLightArray().asBytes()); } } } if (this.e()) { packetdataserializer.writeBytes(chunk.getBiomeIndex()); } return j; } protected int a(Chunk chunk, boolean flag, int i) { int j = 0; ChunkSection[] achunksection = chunk.getSections(); int k = 0; for (int l = achunksection.length; k < l; ++k) { ChunkSection chunksection = achunksection[k]; if (chunksection != Chunk.a && (!this.e() || !chunksection.a()) && (i & 1 << k) != 0) { j += chunksection.getBlocks().a(); j += chunksection.getEmittedLightArray().asBytes().length; if (flag) { j += chunksection.getSkyLightArray().asBytes().length; } } } if (this.e()) { j += chunk.getBiomeIndex().length; } return j; } public boolean e() { return this.f; } }