Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Little endian io #55

Merged
merged 5 commits into from
Jan 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ apply plugin: 'jacoco'

group = 'net.querz.nbt'
archivesBaseName = 'nbt'
version = '5.5'
version = '6.0'
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
compileJava.options.encoding = 'UTF-8'
Expand Down
115 changes: 95 additions & 20 deletions src/main/java/net/querz/mca/Chunk.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@

public class Chunk {

public static final int DEFAULT_DATA_VERSION = 1628;
public static final int DEFAULT_DATA_VERSION = 2567;

private boolean partial;
private boolean raw;

private int lastMCAUpdate;

Expand Down Expand Up @@ -59,6 +60,12 @@ private void initReferences(long loadFlags) {
if (data == null) {
throw new NullPointerException("data cannot be null");
}

if ((loadFlags != ALL_DATA) && (loadFlags & RAW) != 0) {
raw = true;
return;
}

CompoundTag level;
if ((level = data.getCompoundTag("Level")) == null) {
throw new IllegalArgumentException("data does not contain \"Level\" tag");
Expand Down Expand Up @@ -121,8 +128,6 @@ private void initReferences(long loadFlags) {
if (loadFlags != ALL_DATA) {
data = null;
partial = true;
} else {
partial = false;
}
}

Expand Down Expand Up @@ -224,6 +229,7 @@ public int getBiomeAt(int blockX, int blockY, int blockZ) {

@Deprecated
public void setBiomeAt(int blockX, int blockZ, int biomeID) {
checkRaw();
if (dataVersion < 2202) {
if (biomes == null || biomes.length != 256) {
biomes = new int[256];
Expand Down Expand Up @@ -254,6 +260,7 @@ public void setBiomeAt(int blockX, int blockZ, int biomeID) {
* When set to a negative number, Minecraft will replace it with the block column's default biome.
*/
public void setBiomeAt(int blockX, int blockY, int blockZ, int biomeID) {
checkRaw();
if (dataVersion < 2202) {
if (biomes == null || biomes.length != 256) {
biomes = new int[256];
Expand All @@ -274,7 +281,7 @@ public void setBiomeAt(int blockX, int blockY, int blockZ, int biomeID) {
}

int getBiomeIndex(int biomeX, int biomeY, int biomeZ) {
return biomeY * 64 + biomeZ * 4 + biomeX;
return biomeY * 16 + biomeZ * 4 + biomeX;
}

public CompoundTag getBlockStateAt(int blockX, int blockY, int blockZ) {
Expand All @@ -297,6 +304,7 @@ public CompoundTag getBlockStateAt(int blockX, int blockY, int blockZ) {
* Recalculating the Palette should only be executed once right before saving the Chunk to file.
*/
public void setBlockStateAt(int blockX, int blockY, int blockZ, CompoundTag state, boolean cleanup) {
checkRaw();
int sectionIndex = MCAUtil.blockToChunk(blockY);
Section section = sections[sectionIndex];
if (section == null) {
Expand All @@ -318,6 +326,7 @@ public int getDataVersion() {
* @param dataVersion The DataVersion to be set.
*/
public void setDataVersion(int dataVersion) {
checkRaw();
this.dataVersion = dataVersion;
}

Expand All @@ -333,6 +342,7 @@ public int getLastMCAUpdate() {
* @param lastMCAUpdate The time in seconds since 1970-01-01.
*/
public void setLastMCAUpdate(int lastMCAUpdate) {
checkRaw();
this.lastMCAUpdate = lastMCAUpdate;
}

Expand All @@ -348,6 +358,7 @@ public String getStatus() {
* @param status The generation status of this chunk.
*/
public void setStatus(String status) {
checkRaw();
this.status = status;
}

Expand All @@ -366,6 +377,7 @@ public Section getSection(int sectionY) {
* @param section The section to be set.
*/
public void setSection(int sectionY, Section section) {
checkRaw();
sections[sectionY] = section;
}

Expand All @@ -381,6 +393,7 @@ public long getLastUpdate() {
* @param lastUpdate The UNIX timestamp.
*/
public void setLastUpdate(long lastUpdate) {
checkRaw();
this.lastUpdate = lastUpdate;
}

Expand All @@ -396,6 +409,7 @@ public long getInhabitedTime() {
* @param inhabitedTime The time in ticks.
*/
public void setInhabitedTime(long inhabitedTime) {
checkRaw();
this.inhabitedTime = inhabitedTime;
}

Expand All @@ -413,6 +427,7 @@ public int[] getBiomes() {
* or is <code>null</code>
*/
public void setBiomes(int[] biomes) {
checkRaw();
if (biomes != null) {
if (dataVersion < 2202 && biomes.length != 256 || dataVersion >= 2202 && biomes.length != 1024) {
throw new IllegalArgumentException("biomes array must have a length of " + (dataVersion < 2202 ? "256" : "1024"));
Expand All @@ -433,6 +448,7 @@ public CompoundTag getHeightMaps() {
* @param heightMaps The height maps.
*/
public void setHeightMaps(CompoundTag heightMaps) {
checkRaw();
this.heightMaps = heightMaps;
}

Expand All @@ -448,6 +464,7 @@ public CompoundTag getCarvingMasks() {
* @param carvingMasks The carving masks.
*/
public void setCarvingMasks(CompoundTag carvingMasks) {
checkRaw();
this.carvingMasks = carvingMasks;
}

Expand All @@ -463,6 +480,7 @@ public ListTag<CompoundTag> getEntities() {
* @param entities The entities.
*/
public void setEntities(ListTag<CompoundTag> entities) {
checkRaw();
this.entities = entities;
}

Expand All @@ -478,6 +496,7 @@ public ListTag<CompoundTag> getTileEntities() {
* @param tileEntities The tile entities of this chunk.
*/
public void setTileEntities(ListTag<CompoundTag> tileEntities) {
checkRaw();
this.tileEntities = tileEntities;
}

Expand All @@ -493,6 +512,7 @@ public ListTag<CompoundTag> getTileTicks() {
* @param tileTicks Thee tile ticks.
*/
public void setTileTicks(ListTag<CompoundTag> tileTicks) {
checkRaw();
this.tileTicks = tileTicks;
}

Expand All @@ -508,6 +528,7 @@ public ListTag<CompoundTag> getLiquidTicks() {
* @param liquidTicks The liquid ticks.
*/
public void setLiquidTicks(ListTag<CompoundTag> liquidTicks) {
checkRaw();
this.liquidTicks = liquidTicks;
}

Expand All @@ -523,11 +544,12 @@ public ListTag<ListTag<?>> getLights() {
* @param lights The light sources.
*/
public void setLights(ListTag<ListTag<?>> lights) {
checkRaw();
this.lights = lights;
}

/**
* @return THe liquids to be ticked in this chunk.
* @return The liquids to be ticked in this chunk.
*/
public ListTag<ListTag<?>> getLiquidsToBeTicked() {
return liquidsToBeTicked;
Expand All @@ -538,6 +560,7 @@ public ListTag<ListTag<?>> getLiquidsToBeTicked() {
* @param liquidsToBeTicked The liquids to be ticked.
*/
public void setLiquidsToBeTicked(ListTag<ListTag<?>> liquidsToBeTicked) {
checkRaw();
this.liquidsToBeTicked = liquidsToBeTicked;
}

Expand All @@ -553,6 +576,7 @@ public ListTag<ListTag<?>> getToBeTicked() {
* @param toBeTicked The stuff to be ticked.
*/
public void setToBeTicked(ListTag<ListTag<?>> toBeTicked) {
checkRaw();
this.toBeTicked = toBeTicked;
}

Expand All @@ -568,6 +592,7 @@ public ListTag<ListTag<?>> getPostProcessing() {
* @param postProcessing The things to be post processed.
*/
public void setPostProcessing(ListTag<ListTag<?>> postProcessing) {
checkRaw();
this.postProcessing = postProcessing;
}

Expand All @@ -583,6 +608,7 @@ public CompoundTag getStructures() {
* @param structures The data about structures.
*/
public void setStructures(CompoundTag structures) {
checkRaw();
this.structures = structures;
}

Expand All @@ -591,46 +617,95 @@ int getBlockIndex(int blockX, int blockZ) {
}

public void cleanupPalettesAndBlockStates() {
checkRaw();
for (Section section : sections) {
if (section != null) {
section.cleanupPaletteAndBlockStates();
}
}
}

private void checkRaw() {
if (raw) {
throw new UnsupportedOperationException("cannot update field when working with raw data");
}
}

public static Chunk newChunk() {
return newChunk(DEFAULT_DATA_VERSION);
}

public static Chunk newChunk(int dataVersion) {
Chunk c = new Chunk(0);
c.dataVersion = DEFAULT_DATA_VERSION;
c.dataVersion = dataVersion;
c.data = new CompoundTag();
c.data.put("Level", new CompoundTag());
c.status = "mobs_spawned";
return c;
}

/**
* Provides a reference to the full chunk data.
* @return The full chunk data or null if there is none, e.g. when this chunk has only been loaded partially.
*/
public CompoundTag getHandle() {
return data;
}

public CompoundTag updateHandle(int xPos, int zPos) {
if (raw) {
return data;
}

data.putInt("DataVersion", dataVersion);
CompoundTag level = data.getCompoundTag("Level");
level.putInt("xPos", xPos);
level.putInt("zPos", zPos);
level.putLong("LastUpdate", lastUpdate);
level.putLong("InhabitedTime", inhabitedTime);
if (dataVersion < 2202) {
if (biomes != null && biomes.length == 256) level.putIntArray("Biomes", biomes);
if (biomes != null && biomes.length == 256) {
level.putIntArray("Biomes", biomes);
}
} else {
if (biomes != null && biomes.length == 1024) level.putIntArray("Biomes", biomes);
}
if (heightMaps != null) level.put("Heightmaps", heightMaps);
if (carvingMasks != null) level.put("CarvingMasks", carvingMasks);
if (entities != null) level.put("Entities", entities);
if (tileEntities != null) level.put("TileEntities", tileEntities);
if (tileTicks != null) level.put("TileTicks", tileTicks);
if (liquidTicks != null) level.put("LiquidTicks", liquidTicks);
if (lights != null) level.put("Lights", lights);
if (liquidsToBeTicked != null) level.put("LiquidsToBeTicked", liquidsToBeTicked);
if (toBeTicked != null) level.put("ToBeTicked", toBeTicked);
if (postProcessing != null) level.put("PostProcessing", postProcessing);
if (biomes != null && biomes.length == 1024) {
level.putIntArray("Biomes", biomes);
}
}
if (heightMaps != null) {
level.put("Heightmaps", heightMaps);
}
if (carvingMasks != null) {
level.put("CarvingMasks", carvingMasks);
}
if (entities != null) {
level.put("Entities", entities);
}
if (tileEntities != null) {
level.put("TileEntities", tileEntities);
}
if (tileTicks != null) {
level.put("TileTicks", tileTicks);
}
if (liquidTicks != null) {
level.put("LiquidTicks", liquidTicks);
}
if (lights != null) {
level.put("Lights", lights);
}
if (liquidsToBeTicked != null) {
level.put("LiquidsToBeTicked", liquidsToBeTicked);
}
if (toBeTicked != null) {
level.put("ToBeTicked", toBeTicked);
}
if (postProcessing != null) {
level.put("PostProcessing", postProcessing);
}
level.putString("Status", status);
if (structures != null) level.put("Structures", structures);
if (structures != null) {
level.put("Structures", structures);
}
ListTag<CompoundTag> sections = new ListTag<>(CompoundTag.class);
for (int i = 0; i < this.sections.length; i++) {
if (this.sections[i] != null) {
Expand Down
37 changes: 18 additions & 19 deletions src/main/java/net/querz/mca/LoadFlags.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
package net.querz.mca;

public class LoadFlags {

public static long BIOMES = 0x0001;
public static long HEIGHTMAPS = 0x0002;
public static long CARVING_MASKS = 0x0004;
public static long ENTITIES = 0x0008;
public static long TILE_ENTITIES = 0x0010;
public static long TILE_TICKS = 0x0040;
public static long LIQUID_TICKS = 0x0080;
public static long TO_BE_TICKED = 0x0100;
public static long POST_PROCESSING = 0x0200;
public static long STRUCTURES = 0x0400;
public static long BLOCK_LIGHTS = 0x0800;
public static long BLOCK_STATES = 0x1000;
public static long SKY_LIGHT = 0x2000;
public static long LIGHTS = 0x4000;
public static long LIQUIDS_TO_BE_TICKED = 0x8000;

public static long ALL_DATA = 0xffffffffffffffffL;
public final class LoadFlags {

public static final long BIOMES = 0x00001;
public static final long HEIGHTMAPS = 0x00002;
public static final long CARVING_MASKS = 0x00004;
public static final long ENTITIES = 0x00008;
public static final long TILE_ENTITIES = 0x00010;
public static final long TILE_TICKS = 0x00040;
public static final long LIQUID_TICKS = 0x00080;
public static final long TO_BE_TICKED = 0x00100;
public static final long POST_PROCESSING = 0x00200;
public static final long STRUCTURES = 0x00400;
public static final long BLOCK_LIGHTS = 0x00800;
public static final long BLOCK_STATES = 0x01000;
public static final long SKY_LIGHT = 0x02000;
public static final long LIGHTS = 0x04000;
public static final long LIQUIDS_TO_BE_TICKED = 0x08000;
public static final long RAW = 0x10000;

public static final long ALL_DATA = 0xffffffffffffffffL;
}
Loading