properly fixed statelist length errors

This commit is contained in:
Pierre Kisters 2020-08-15 21:33:04 +02:00
parent 5e7d00e438
commit ae40a6f47e
2 changed files with 38 additions and 14 deletions

View File

@ -3,6 +3,8 @@ package org.dynmap.fabric_1_16_1;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.ListTag;
import net.minecraft.util.collection.PackedIntegerArray; import net.minecraft.util.collection.PackedIntegerArray;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.WordPackedArray;
import org.dynmap.Log; import org.dynmap.Log;
import org.dynmap.renderer.DynmapBlockState; import org.dynmap.renderer.DynmapBlockState;
@ -128,10 +130,10 @@ public class ChunkSnapshot {
public static class StateListException extends Exception { public static class StateListException extends Exception {
private static boolean loggedOnce = false; private static boolean loggedOnce = false;
public StateListException(int x, int z, int expectedLength, int actualLength) { public StateListException(int x, int z, int actualLength, int expectedLength, int expectedLegacyLength) {
if (Log.verbose || !loggedOnce) { if (Log.verbose || !loggedOnce) {
loggedOnce = true; loggedOnce = true;
Log.info("Skipping chunk at x=" + x + ",z=" + z + ". Expected statelist of length " + expectedLength + " but got " + actualLength + ". This can happen if the chunk was not yet converted to the 1.16 format which can be fixed by visiting the chunk."); Log.info("Skipping chunk at x=" + x + ",z=" + z + ". Expected statelist of length " + expectedLength + " or " + expectedLegacyLength + " but got " + actualLength + ". This can happen if the chunk was not yet converted to the 1.16 format which can be fixed by visiting the chunk.");
if (!Log.verbose) { if (!Log.verbose) {
Log.info("You will only see this message once. Turn on verbose logging in the configuration to see all messages."); Log.info("You will only see this message once. Turn on verbose logging in the configuration to see all messages.");
} }
@ -198,20 +200,30 @@ public class ChunkSnapshot {
} }
} }
PackedIntegerArray db = null;
WordPackedArray dbp = null;
int bitsperblock = (statelist.length * 64) / 4096; int bitsperblock = (statelist.length * 64) / 4096;
int expectedStatelistLength = (4096 + (64 / bitsperblock) - 1) / (64 / bitsperblock); int expectedStatelistLength = (4096 + (64 / bitsperblock) - 1) / (64 / bitsperblock);
if (expectedStatelistLength != statelist.length) { if (statelist.length == expectedStatelistLength) {
throw new StateListException(x, z, expectedStatelistLength, statelist.length); db = new PackedIntegerArray(bitsperblock, 4096, statelist);
} else {
int expectedLegacyStatelistLength = MathHelper.roundUpToMultiple(bitsperblock * 4096, 64) / 64;
if (statelist.length == expectedLegacyStatelistLength) {
dbp = new WordPackedArray(bitsperblock, 4096, statelist);
} else {
throw new StateListException(x, z, statelist.length, expectedStatelistLength, expectedLegacyStatelistLength);
}
} }
PackedIntegerArray db = new PackedIntegerArray(bitsperblock, 4096, statelist);
if (bitsperblock > 8) { // Not palette if (bitsperblock > 8) { // Not palette
for (int j = 0; j < 4096; j++) { for (int j = 0; j < 4096; j++) {
states[j] = DynmapBlockState.getStateByGlobalIndex(db.get(j)); int v = db != null ? db.get(j) : dbp.get(j);
states[j] = DynmapBlockState.getStateByGlobalIndex(v);
} }
} else { } else {
for (int j = 0; j < 4096; j++) { for (int j = 0; j < 4096; j++) {
int v = db.get(j); int v = db != null ? db.get(j) : dbp.get(j);
states[j] = (v < palette.length) ? palette[v] : DynmapBlockState.AIR; states[j] = (v < palette.length) ? palette[v] : DynmapBlockState.AIR;
} }
} }

View File

@ -3,6 +3,8 @@ package org.dynmap.fabric_1_16_2;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.ListTag;
import net.minecraft.util.collection.PackedIntegerArray; import net.minecraft.util.collection.PackedIntegerArray;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.WordPackedArray;
import org.dynmap.Log; import org.dynmap.Log;
import org.dynmap.renderer.DynmapBlockState; import org.dynmap.renderer.DynmapBlockState;
@ -128,10 +130,10 @@ public class ChunkSnapshot {
public static class StateListException extends Exception { public static class StateListException extends Exception {
private static boolean loggedOnce = false; private static boolean loggedOnce = false;
public StateListException(int x, int z, int expectedLength, int actualLength) { public StateListException(int x, int z, int actualLength, int expectedLength, int expectedLegacyLength) {
if (Log.verbose || !loggedOnce) { if (Log.verbose || !loggedOnce) {
loggedOnce = true; loggedOnce = true;
Log.info("Skipping chunk at x=" + x + ",z=" + z + ". Expected statelist of length " + expectedLength + " but got " + actualLength + ". This can happen if the chunk was not yet converted to the 1.16 format which can be fixed by visiting the chunk."); Log.info("Skipping chunk at x=" + x + ",z=" + z + ". Expected statelist of length " + expectedLength + " or " + expectedLegacyLength + " but got " + actualLength + ". This can happen if the chunk was not yet converted to the 1.16 format which can be fixed by visiting the chunk.");
if (!Log.verbose) { if (!Log.verbose) {
Log.info("You will only see this message once. Turn on verbose logging in the configuration to see all messages."); Log.info("You will only see this message once. Turn on verbose logging in the configuration to see all messages.");
} }
@ -198,20 +200,30 @@ public class ChunkSnapshot {
} }
} }
PackedIntegerArray db = null;
WordPackedArray dbp = null;
int bitsperblock = (statelist.length * 64) / 4096; int bitsperblock = (statelist.length * 64) / 4096;
int expectedStatelistLength = (4096 + (64 / bitsperblock) - 1) / (64 / bitsperblock); int expectedStatelistLength = (4096 + (64 / bitsperblock) - 1) / (64 / bitsperblock);
if (expectedStatelistLength != statelist.length) { if (statelist.length == expectedStatelistLength) {
throw new StateListException(x, z, expectedStatelistLength, statelist.length); db = new PackedIntegerArray(bitsperblock, 4096, statelist);
} else {
int expectedLegacyStatelistLength = MathHelper.roundUpToMultiple(bitsperblock * 4096, 64) / 64;
if (statelist.length == expectedLegacyStatelistLength) {
dbp = new WordPackedArray(bitsperblock, 4096, statelist);
} else {
throw new StateListException(x, z, statelist.length, expectedStatelistLength, expectedLegacyStatelistLength);
}
} }
PackedIntegerArray db = new PackedIntegerArray(bitsperblock, 4096, statelist);
if (bitsperblock > 8) { // Not palette if (bitsperblock > 8) { // Not palette
for (int j = 0; j < 4096; j++) { for (int j = 0; j < 4096; j++) {
states[j] = DynmapBlockState.getStateByGlobalIndex(db.get(j)); int v = db != null ? db.get(j) : dbp.get(j);
states[j] = DynmapBlockState.getStateByGlobalIndex(v);
} }
} else { } else {
for (int j = 0; j < 4096; j++) { for (int j = 0; j < 4096; j++) {
int v = db.get(j); int v = db != null ? db.get(j) : dbp.get(j);
states[j] = (v < palette.length) ? palette[v] : DynmapBlockState.AIR; states[j] = (v < palette.length) ? palette[v] : DynmapBlockState.AIR;
} }
} }