NBT icon indicating copy to clipboard operation
NBT copied to clipboard

Populating a new chunk from scratch results in an ArrayIndexOutOfBoundsException

Open toddharrison opened this issue 4 years ago • 4 comments

I am using this library to create an entirely new chunk copied from an existing chunk from the bottom up that I've loaded from elsewhere. I plan on making changes to the chunk as it copies in the future, but for now it's just a straight copy where I have to manually create the blockState for each x, y, and z. As it builds up the copied chunk, it seems to work fine until it hits a certain number of items in the palette. I get this exception:

java.lang.ArrayIndexOutOfBoundsException: Index 320 out of bounds for length 320
[20:15:52 WARN]:        at com.briarcraft.shadow.querz.mca.Section.setPaletteIndex(Section.java:199)
[20:15:52 WARN]:        at com.briarcraft.shadow.querz.mca.Section.adjustBlockStateBits(Section.java:294)
[20:15:52 WARN]:        at com.briarcraft.shadow.querz.mca.Section.setBlockStateAt(Section.java:138)
[20:15:52 WARN]:        at com.briarcraft.shadow.querz.mca.Chunk.setBlockStateAt(Chunk.java:305)

I believe this is happening when it has to resize the blockdata palette index byte size because we've added one too many palette items. In Section on line 137 I see some logic that looks like it's meant to address the issue.

I'm not sure if there is an issue with me manually creating the blockState or something else causing this issue. Thanks for your assistance!

toddharrison avatar Jan 03 '21 03:01 toddharrison

setPaletteIndex does not change the size of the blockStates array (as stated in the javadoc). You will have to know its size beforehand or adjust its size manually.

Querz avatar Jan 03 '21 04:01 Querz

So if set it to the max number of blocks, will it reduce when I run the cleanup or will I need to do that as well? I suppose I could also do preprocessing, but I was doing it in a streaming manner instead for performance.

toddharrison avatar Jan 03 '21 04:01 toddharrison

You could set the initial length of the blockStates to its maximum length (4096) and at the end after creating a new Section object call cleanupPaletteAndBlockStates, but then you could also just set the palette indexes manually without using setPaletteIndex, something like this:

CompoundTag sectionData = new CompoundTag();
long[] blockStates = new long[4096];
ListTag<CompoundTag> palette = new ListTag<>(CompoundTag.class);

for (int index = 0; index < 4096; index++) {
  // calculate paletteIndex here
  blockStates[index] = paletteIndex; // setting palette index manually
}

sectionData.put("Palette", palette);
sectionData.put("BlockStates", blockStates);

Section section = new Section(sectionData, 2584);
section.cleanupPaletteAndBlockStates();

Querz avatar Jan 03 '21 04:01 Querz

Thanks! Giving it a shot. Want me to close this?

toddharrison avatar Jan 04 '21 03:01 toddharrison