question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Problems with ChunkSection.read : IllegalArgumentException: Expected 1024 longs but got 0 longs

See original GitHub issue

I 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:closed
  • Created 2 years ago
  • Comments:13 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
nickelprocommented, Jan 19, 2022

No idea if its related, but this (from DataPalette.java) looks wrong to me:

private static Palette readPalette(PaletteType paletteType, int bitsPerEntry, NetInput in) throws IOException {
    if (bitsPerEntry > paletteType.getMaxBitsPerEntry()) {
        return new GlobalPalette();
    }
    if (bitsPerEntry == 0) {
        return new SingletonPalette(in);
    }
    if (bitsPerEntry <= paletteType.getMinBitsPerEntry()) {
        return new ListPalette(bitsPerEntry, in);
    } else {
        return new MapPalette(bitsPerEntry, in);
    }
}

When bitsPerEntry is <= the MinBitsPerEntry, you should use the MinBitsPerEntry. Again from vanilla’s PalettedContainer.java:

@Override
public <A> Configuration<A> getConfiguration(IdMap<A> idMap, int n) {
    Configuration configuration = switch (n) {
        case 0 -> new Configuration(SINGLE_VALUE_PALETTE_FACTORY, n);
        case 1, 2, 3, 4 -> new Configuration(LINEAR_PALETTE_FACTORY, 4);
        case 5, 6, 7, 8 -> new Configuration(HASHMAP_PALETTE_FACTORY, n);
        default -> new Configuration(GLOBAL_PALETTE_FACTORY, Mth.ceillog2(idMap.size()));
    };
    return configuration;
}

This is the configuration manager for BlockState sections, where n is the bitsPerEntry. As you can see, for any bitsPerEntry 1-4, the bits value passed to the Palette configuration is always 4.

For biomes its different, and the bitsPerEntry is always used as is when <= 3:

@Override
public <A> Configuration<A> getConfiguration(IdMap<A> idMap, int n) {
    return switch (n) {
        case 0 -> new Configuration(SINGLE_VALUE_PALETTE_FACTORY, n);
        case 1, 2, 3 -> new Configuration(LINEAR_PALETTE_FACTORY, n);
        default -> new Configuration(GLOBAL_PALETTE_FACTORY, Mth.ceillog2(idMap.size()));
    };
}
0reactions
Camotoycommented, Jul 30, 2022

Most likely. Thanks for the bump.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Expected 1024 longs but got 0 longs - GeyserMC/MCProtocolLib
Problems with ChunkSection.read : IllegalArgumentException: Expected 1024 longs but got 0 longs. This issue has been created since 2022-01-19 ...
Read more >
https://hub.spigotmc.org/stash/projects/EMC/repos/...
java/net/minecraft/server/ChunkSection.java | 26 +- . ... + public long activatedTick = 0; + public boolean fromMobSpawner; + public void inactiveTick() ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found