Progress converting chunkloaders
This commit is contained in:
parent
5390a33fa3
commit
1a13794b8b
|
@ -61,8 +61,7 @@ dependencies {
|
|||
api ("commons-io:commons-io:2.5")
|
||||
api ("org.spongepowered:configurate-hocon:4.1.2")
|
||||
api ("org.spongepowered:configurate-gson:4.1.2")
|
||||
//api ("com.github.Querz:NBT:4.0")
|
||||
api ("com.github.BlueMap-Minecraft:BlueNBT:v1.2.0")
|
||||
api ("com.github.BlueMap-Minecraft:BlueNBT:v1.2.1")
|
||||
api ("org.apache.commons:commons-dbcp2:2.9.0")
|
||||
api ("io.airlift:aircompressor:0.24")
|
||||
|
||||
|
|
|
@ -24,90 +24,79 @@
|
|||
*/
|
||||
package de.bluecolored.bluemap.core.mca;
|
||||
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
import de.bluecolored.bluemap.core.mca.data.ChunkData;
|
||||
import de.bluecolored.bluemap.core.mca.data.HeightmapsData;
|
||||
import de.bluecolored.bluemap.core.mca.data.SectionData;
|
||||
import de.bluecolored.bluemap.core.world.Biome;
|
||||
import de.bluecolored.bluemap.core.world.BlockState;
|
||||
import de.bluecolored.bluemap.core.world.LightData;
|
||||
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
public class ChunkAnvil116 /* extends MCAChunk */ {
|
||||
private static final long[] EMPTY_LONG_ARRAY = new long[0];
|
||||
public class ChunkAnvil116 extends MCAChunk {
|
||||
|
||||
/*
|
||||
private final boolean isGenerated;
|
||||
private final boolean hasLight;
|
||||
|
||||
private boolean isGenerated;
|
||||
private boolean hasLight;
|
||||
private final long inhabitedTime;
|
||||
|
||||
private long inhabitedTime;
|
||||
private final int sectionMin, sectionMax;
|
||||
private final Section[] sections;
|
||||
|
||||
private int sectionMin, sectionMax;
|
||||
private Section[] sections;
|
||||
private final int[] biomes;
|
||||
|
||||
private int[] biomes;
|
||||
private final long[] oceanFloorHeights;
|
||||
private final long[] worldSurfaceHeights;
|
||||
|
||||
private long[] oceanFloorHeights = EMPTY_LONG_ARRAY;
|
||||
private long[] worldSurfaceHeights = EMPTY_LONG_ARRAY;
|
||||
public ChunkAnvil116(MCAWorld world, ChunkData chunkData) {
|
||||
super(world, chunkData);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ChunkAnvil116(MCAWorld world, CompoundTag chunkTag) {
|
||||
super(world, chunkTag);
|
||||
String status = chunkData.getStatus();
|
||||
boolean generated = status.equals("full");
|
||||
this.hasLight = generated;
|
||||
if (!generated && getWorld().isIgnoreMissingLightData())
|
||||
generated = !status.equals("empty");
|
||||
this.isGenerated = generated;
|
||||
|
||||
CompoundTag levelData = chunkTag.getCompoundTag("Level");
|
||||
this.inhabitedTime = chunkData.getInhabitedTime();
|
||||
|
||||
String status = levelData.getString("Status");
|
||||
this.isGenerated = status.equals("full");
|
||||
this.hasLight = isGenerated;
|
||||
HeightmapsData heightmapsData = chunkData.getHeightmaps();
|
||||
this.worldSurfaceHeights = heightmapsData.getWorldSurface();
|
||||
this.oceanFloorHeights = heightmapsData.getOceanFloor();
|
||||
|
||||
this.inhabitedTime = levelData.getLong("InhabitedTime");
|
||||
SectionData[] sectionDatas = chunkData.getSections();
|
||||
if (sectionDatas != null && sectionDatas.length > 0) {
|
||||
int min = Integer.MAX_VALUE;
|
||||
int max = Integer.MIN_VALUE;
|
||||
|
||||
if (!isGenerated && getWorld().isIgnoreMissingLightData()) {
|
||||
isGenerated = !status.equals("empty");
|
||||
}
|
||||
// find section min/max y
|
||||
for (SectionData sectionData : sectionDatas) {
|
||||
int y = sectionData.getY();
|
||||
if (min > y) min = y;
|
||||
if (max < y) max = y;
|
||||
}
|
||||
|
||||
if (levelData.containsKey("Heightmaps")) {
|
||||
CompoundTag heightmapsTag = levelData.getCompoundTag("Heightmaps");
|
||||
this.worldSurfaceHeights = heightmapsTag.getLongArray("WORLD_SURFACE");
|
||||
this.oceanFloorHeights = heightmapsTag.getLongArray("OCEAN_FLOOR");
|
||||
}
|
||||
|
||||
if (levelData.containsKey("Sections")) {
|
||||
this.sectionMin = Integer.MAX_VALUE;
|
||||
this.sectionMax = Integer.MIN_VALUE;
|
||||
|
||||
ListTag<CompoundTag> sectionsTag = (ListTag<CompoundTag>) levelData.getListTag("Sections");
|
||||
ArrayList<Section> sectionList = new ArrayList<>(sectionsTag.size());
|
||||
|
||||
for (CompoundTag sectionTag : sectionsTag) {
|
||||
if (sectionTag.getListTag("Palette") == null) continue; // ignore empty sections
|
||||
|
||||
Section section = new Section(sectionTag);
|
||||
// load sections into ordered array
|
||||
this.sections = new Section[1 + max - min];
|
||||
for (SectionData sectionData : sectionDatas) {
|
||||
Section section = new Section(sectionData);
|
||||
int y = section.getSectionY();
|
||||
|
||||
if (sectionMin > y) sectionMin = y;
|
||||
if (sectionMax < y) sectionMax = y;
|
||||
if (min > y) min = y;
|
||||
if (max < y) max = y;
|
||||
|
||||
sectionList.add(section);
|
||||
sections[section.sectionY - min] = section;
|
||||
}
|
||||
|
||||
sections = new Section[1 + sectionMax - sectionMin];
|
||||
for (Section section : sectionList) {
|
||||
sections[section.sectionY - sectionMin] = section;
|
||||
}
|
||||
this.sectionMin = min;
|
||||
this.sectionMax = max;
|
||||
} else {
|
||||
sections = new Section[0];
|
||||
this.sections = new Section[0];
|
||||
this.sectionMin = 0;
|
||||
this.sectionMax = 0;
|
||||
}
|
||||
|
||||
Tag<?> tag = levelData.get("Biomes"); //tag can be byte-array or int-array
|
||||
if (tag instanceof ByteArrayTag) {
|
||||
byte[] bs = ((ByteArrayTag) tag).getValue();
|
||||
this.biomes = new int[bs.length];
|
||||
|
||||
for (int i = 0; i < bs.length; i++) {
|
||||
biomes[i] = bs[i] & 0xFF;
|
||||
}
|
||||
}
|
||||
else if (tag instanceof IntArrayTag) {
|
||||
this.biomes = ((IntArrayTag) tag).getValue();
|
||||
}
|
||||
|
||||
if (biomes == null) {
|
||||
this.biomes = new int[0];
|
||||
}
|
||||
this.biomes = chunkData.getBiomes();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -191,54 +180,21 @@ public class ChunkAnvil116 /* extends MCAChunk */ {
|
|||
}
|
||||
|
||||
private static class Section {
|
||||
private static final String AIR_ID = "minecraft:air";
|
||||
private final int sectionY;
|
||||
private final byte[] blockLight;
|
||||
private final byte[] skyLight;
|
||||
private final long[] blocks;
|
||||
private final BlockState[] palette;
|
||||
|
||||
private int sectionY;
|
||||
private byte[] blockLight;
|
||||
private byte[] skyLight;
|
||||
private long[] blocks;
|
||||
private BlockState[] palette;
|
||||
private final int bitsPerBlock;
|
||||
|
||||
private int bitsPerBlock;
|
||||
public Section(SectionData sectionData) {
|
||||
this.sectionY = sectionData.getY();
|
||||
this.blockLight = sectionData.getBlockLight();
|
||||
this.skyLight = sectionData.getSkyLight();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Section(CompoundTag sectionData) {
|
||||
this.sectionY = sectionData.get("Y", NumberTag.class).asInt();
|
||||
this.blockLight = sectionData.getByteArray("BlockLight");
|
||||
this.skyLight = sectionData.getByteArray("SkyLight");
|
||||
this.blocks = sectionData.getLongArray("BlockStates");
|
||||
|
||||
if (blocks.length < 256 && blocks.length > 0) blocks = Arrays.copyOf(blocks, 256);
|
||||
if (blockLight.length < 2048 && blockLight.length > 0) blockLight = Arrays.copyOf(blockLight, 2048);
|
||||
if (skyLight.length < 2048 && skyLight.length > 0) skyLight = Arrays.copyOf(skyLight, 2048);
|
||||
|
||||
//read block palette
|
||||
ListTag<CompoundTag> paletteTag = (ListTag<CompoundTag>) sectionData.getListTag("Palette");
|
||||
if (paletteTag != null) {
|
||||
this.palette = new BlockState[paletteTag.size()];
|
||||
for (int i = 0; i < this.palette.length; i++) {
|
||||
CompoundTag stateTag = paletteTag.get(i);
|
||||
|
||||
String id = stateTag.getString("Name"); //shortcut to save time and memory
|
||||
if (id.equals(AIR_ID)) {
|
||||
palette[i] = BlockState.AIR;
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
|
||||
if (stateTag.containsKey("Properties")) {
|
||||
CompoundTag propertiesTag = stateTag.getCompoundTag("Properties");
|
||||
for (Entry<String, Tag<?>> property : propertiesTag) {
|
||||
properties.put(property.getKey().toLowerCase(), ((StringTag) property.getValue()).getValue().toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
palette[i] = new BlockState(id, properties);
|
||||
}
|
||||
} else {
|
||||
this.palette = new BlockState[0];
|
||||
}
|
||||
this.blocks = sectionData.getBlockStatesData();
|
||||
this.palette = sectionData.getPalette();
|
||||
|
||||
this.bitsPerBlock = this.blocks.length >> 6; // available longs * 64 (bits per long) / 4096 (blocks per section) (floored result)
|
||||
}
|
||||
|
@ -280,6 +236,4 @@ public class ChunkAnvil116 /* extends MCAChunk */ {
|
|||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
|
|
@ -96,8 +96,8 @@ public abstract class MCAChunk implements Chunk {
|
|||
/*
|
||||
if (version < 2200) return new ChunkAnvil113(world, chunkData);
|
||||
if (version < 2500) return new ChunkAnvil115(world, chunkData);
|
||||
if (version < 2844) return new ChunkAnvil116(world, chunkData);
|
||||
*/
|
||||
if (version < 2844) return new ChunkAnvil116(world, chunkData);
|
||||
|
||||
return new ChunkAnvil118(world, chunkData);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ public class MCAMath {
|
|||
int firstLong = bitIndex >> 6; // index / 64
|
||||
int bitoffset = bitIndex & 0x3F; // Math.floorMod(index, 64)
|
||||
|
||||
if (firstLong >= data.length) return 0;
|
||||
long value = data[firstLong] >>> bitoffset;
|
||||
|
||||
if (bitoffset > 0 && firstLong + 1 < data.length) {
|
||||
|
|
|
@ -14,4 +14,7 @@ public class ChunkData {
|
|||
private HeightmapsData heightmaps = EMPTY_HEIGHTMAPS_DATA;
|
||||
private @Nullable SectionData[] sections = null;
|
||||
|
||||
// <= 1.16
|
||||
private int[] biomes;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package de.bluecolored.bluemap.core.mca.data;
|
||||
|
||||
import de.bluecolored.bluemap.core.world.BlockState;
|
||||
import de.bluecolored.bluenbt.NBTName;
|
||||
import lombok.Getter;
|
||||
|
||||
|
@ -7,7 +8,9 @@ import lombok.Getter;
|
|||
@SuppressWarnings("FieldMayBeFinal")
|
||||
public class SectionData {
|
||||
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
|
||||
private static final long[] EMPTY_LONG_ARRAY = new long[0];
|
||||
private static final BlockStatesData EMPTY_BLOCKSTATESDATA = new BlockStatesData();
|
||||
private static final BlockState[] EMPTY_BLOCKSTATE_ARRAY = new BlockState[0];
|
||||
private static final BiomesData EMPTY_BIOMESDATA = new BiomesData();
|
||||
|
||||
private int y = 0;
|
||||
|
@ -17,4 +20,9 @@ public class SectionData {
|
|||
private BlockStatesData blockStates = EMPTY_BLOCKSTATESDATA;
|
||||
private BiomesData biomes = EMPTY_BIOMESDATA;
|
||||
|
||||
// <= 1.16
|
||||
@NBTName("BlockStates")
|
||||
private long[] blockStatesData = EMPTY_LONG_ARRAY;
|
||||
private BlockState[] palette = EMPTY_BLOCKSTATE_ARRAY;
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue