Problems with ChunkSection.read : IllegalArgumentException: Expected 1024 longs but got 0 longs
See original GitHub issueI have had some issues with ChunkSection.read on some servers. The issue is very easily reproducible on mc.hypixel.net by just connecting to the server.
Disconnected: java.lang.IllegalArgumentException: Expected 1024 longs but got 0 longs
java.lang.IllegalArgumentException: Expected 1024 longs but got 0 longs
at com.github.steveice10.mc.protocol.data.game.chunk.BitStorage.<init>(BitStorage.java:62)
at com.github.steveice10.mc.protocol.data.game.chunk.DataPalette.read(DataPalette.java:46)
at com.github.steveice10.mc.protocol.data.game.chunk.ChunkSection.read(ChunkSection.java:30)
at Main$SessionAdapterImpl.packetReceived(Main.java:48)
at com.github.steveice10.packetlib.tcp.TcpSession.callPacketReceived(TcpSession.java:156)
at com.github.steveice10.packetlib.tcp.TcpSession.lambda$channelRead0$2(TcpSession.java:375)
at io.netty.channel.DefaultEventLoop.run(DefaultEventLoop.java:54)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
The issue seems to be that MCProtocolLib reads bitsPerEntry=16 and then this length is equal to 0. I can’t figure out where the problem is tho. The BitStorage implementation seems fine and I was not able to find any issue prior to that read. Also note that the issue happened on the first iteration of ChunkSection.read on a particular chunk. The first bytes of the chunkData where: [0 0 16 0 0 35 4 -1…], with the first two bytes being the blockCount, the third being bitsPerEntry and the fourth being the long array length varint. The whole chunkData in this case had length 98646 Removing the throw IllegalArgumentException in BitStorage caused the ChunkSection.read to have different problems (like negative bitsPerEntry), meaning that bitsPerEntry should not be 16 or the 0 for the long array length varint is not meant to be 0.
Sample code here:
import com.github.steveice10.mc.auth.data.GameProfile;
import com.github.steveice10.mc.auth.util.UUIDSerializer;
import com.github.steveice10.mc.protocol.MinecraftProtocol;
import com.github.steveice10.mc.protocol.data.game.chunk.ChunkSection;
import com.github.steveice10.mc.protocol.data.game.chunk.DataPalette;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundLoginPacket;
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLevelChunkWithLightPacket;
import com.github.steveice10.packetlib.Session;
import com.github.steveice10.packetlib.event.session.DisconnectedEvent;
import com.github.steveice10.packetlib.event.session.SessionAdapter;
import com.github.steveice10.packetlib.io.stream.StreamNetInput;
import com.github.steveice10.packetlib.packet.Packet;
import com.github.steveice10.packetlib.tcp.TcpClientSession;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import static java.util.concurrent.TimeUnit.MINUTES;
public class Main {
public static void main(String[] args) {
GameProfile gameProfile = new GameProfile(UUIDSerializer.fromString("REDACTED"), "MatteCarra");
String accessToken = "REDACTED";
Session session = new TcpClientSession("mc.hypixel.net", 25565, new MinecraftProtocol(gameProfile, accessToken));
try {
SessionAdapterImpl listener = new SessionAdapterImpl();
session.addListener(listener);
session.connect();
listener.login.await(1, MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
session.disconnect("Login test complete.");
}
}
private static class SessionAdapterImpl extends SessionAdapter {
@Override
public void packetReceived(Session session, Packet packet) {
if (packet instanceof ClientboundLevelChunkWithLightPacket) {
StreamNetInput dataIn = new StreamNetInput(new ByteArrayInputStream(((ClientboundLevelChunkWithLightPacket) packet).getChunkData()));
for(int i = 0; i < 16; i++) {
try {
ChunkSection.read(dataIn, DataPalette.GLOBAL_PALETTE_BITS_PER_ENTRY);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public void disconnected(DisconnectedEvent event) {
System.err.println("Disconnected: " + event.getReason());
if (event.getCause() != null) {
event.getCause().printStackTrace();
}
}
}
}
Note that the chunk section = 16 is correct in the hypixel hub, but it’s not relevant because this fails at the first iteration of the for
Issue Analytics
- State:
- Created 2 years ago
- Comments:13 (7 by maintainers)
Top GitHub Comments
No idea if its related, but this (from DataPalette.java) looks wrong to me:
When
bitsPerEntry
is <= theMinBitsPerEntry
, you should use theMinBitsPerEntry
. Again from vanilla’s PalettedContainer.java:This is the configuration manager for BlockState sections, where
n
is thebitsPerEntry
. As you can see, for anybitsPerEntry
1-4, thebits
value passed to the Palette configuration is always 4.For biomes its different, and the
bitsPerEntry
is always used as is when <= 3:Most likely. Thanks for the bump.