9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-30 12:29:20 +00:00

Whohoo! we can now read mca files!

This commit is contained in:
RePixelatedMC
2024-04-30 11:14:35 +02:00
parent 56eb4b6b84
commit a919b91efb
10 changed files with 236 additions and 30 deletions

View File

@@ -174,7 +174,7 @@ public class CommandDeveloper implements DecreeExecutor {
try {
File[] McaFiles = new File(world.getName(), "region").listFiles((dir, name) -> name.endsWith(".mca"));
for (File mca : McaFiles) {
IrisWorldDump dump = new IrisWorldDump(world, sender());
IrisWorldDump dump = new IrisWorldDump(world, sender(), IrisWorldDump.mode.RAW);
dump.dump();
}
} catch (Exception e) {

View File

@@ -19,8 +19,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReferenceArray;
public class IrisWorldDump {
public static int Failed = 0;
public static int Success = 0;
private KList<MCAFile> mcaList;
private World world;
private File MCADirectory;
@@ -29,8 +27,9 @@ public class IrisWorldDump {
private Engine engine = null;
private Boolean IrisWorld;
private VolmitSender sender;
private mode mode;
public IrisWorldDump(World world, VolmitSender sender) {
public IrisWorldDump(World world, VolmitSender sender, mode mode) {
this.world = world;
this.sender = sender;
this.MCADirectory = new File(world.getWorldFolder(), "region");
@@ -54,6 +53,22 @@ public class IrisWorldDump {
}
}
public enum mode {
RAW {
@Override
public void methodDump() {
}
},
DISK {
@Override
public void methodDump() {
}
};
public abstract void methodDump();
}
public void dump() {
for (MCAFile mca : mcaList) {
AtomicReferenceArray<Chunk> chunks = new AtomicReferenceArray<>(1024);
@@ -68,6 +83,8 @@ public class IrisWorldDump {
for (int z = 0; z < 16; z++) {
for (int y = 0; y < CHUNK_HEIGHT; y++) {
// CompoundTag tag = chunk.getBlockStateAt(x,y,z);
//net.minecraft.world.level.chunk.PalettedContainer;
//net.minecraft.world.level.chunk.storage.ChunkSerializer;
}
}
}
@@ -107,8 +124,8 @@ public class IrisWorldDump {
if (f > 0) {
sender.sendMessage(C.RED +"Failed " + C.GRAY + "to load: " + f + " MCA Regions");
}
Iris.info("Successfull: " + Form.f(Success));
Iris.info("Failed: " + Form.f(Failed));
Iris.info("Successfull: " + Form.f(l));
Iris.info("Failed: " + Form.f(f));
return mcaFiles;
}

View File

@@ -162,17 +162,11 @@ public class Chunk {
if (sectionIndex > 15 || sectionIndex < 0) {
continue;
}
try {
Section newSection = new Section(section, dataVersion, loadFlags);
if (newSection.isEmpty()) {
continue;
}
sections.put(sectionIndex, newSection);
IrisWorldDump.Success++;
} catch (Exception e) {
IrisWorldDump.Failed++;
// e.printStackTrace();
Section newSection = new Section(section, dataVersion, loadFlags);
if (newSection.isEmpty()) {
continue;
}
sections.put(sectionIndex, newSection);
}
}

View File

@@ -43,7 +43,11 @@ public class Section {
return;
}
palette = INMS.get().createPalette();
palette.readFromSection(sectionRoot);
try {
palette.readFromSection(sectionRoot);
} catch (Exception e) {
e.printStackTrace();
}
ByteArrayTag blockLight = sectionRoot.getByteArrayTag("BlockLight");
ByteArrayTag skyLight = sectionRoot.getByteArrayTag("SkyLight");
this.blockLight = blockLight != null ? blockLight.getValue() : null;

View File

@@ -0,0 +1,112 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2022 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* abyte with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.nbt.mca.palette;
import org.apache.commons.lang3.Validate;
// todo Cool idea but im way to dumb for this for now
public class MCABitStorageByteArray {
private final byte[] data;
private final int bits;
private final int mask;
private final int size;
private final int valuesPerByte;
private final int divideMul;
private final int divideAdd;
private final int divideShift;
public MCABitStorageByteArray(int bits, int length) {
this(bits, length, null);
}
public MCABitStorageByteArray(int bits, int length, byte[] data) {
Validate.inclusiveBetween(1L, 8L, bits); // Ensure bits are between 1 and 8
this.size = length;
this.bits = bits;
this.mask = (1 << bits) - 1;
this.valuesPerByte = 8 / bits;
int[] divisionParams = computeDivisionParameters(this.valuesPerByte);
this.divideMul = divisionParams[0];
this.divideAdd = divisionParams[1];
this.divideShift = divisionParams[2];
int numBytes = (length + this.valuesPerByte - 1) / this.valuesPerByte;
if (data != null) {
if (data.length != numBytes)
throw new IllegalArgumentException("Data array length does not match the required size.");
this.data = data;
} else {
this.data = new byte[numBytes];
}
}
private int[] computeDivisionParameters(int denom) {
long two32 = 1L << 32;
long magic = two32 / denom;
int shift = 0;
while ((1L << (shift + 32)) < magic * denom) {
shift++;
}
return new int[]{(int) magic, 0, shift};
}
private int cellIndex(int index) {
long indexLong = Integer.toUnsignedLong(this.divideMul);
long addLong = Integer.toUnsignedLong(this.divideAdd);
return (int) ((index * indexLong + addLong) >>> 32 >>> this.divideShift);
}
public int getAndSet(int index, int newValue) {
Validate.inclusiveBetween(0L, (this.size - 1), index);
Validate.inclusiveBetween(0L, this.mask, newValue);
int byteIndex = cellIndex(index);
int bitOffset = (index - byteIndex * this.valuesPerByte) * this.bits;
int currentValue = (this.data[byteIndex] >> bitOffset) & this.mask;
this.data[byteIndex] = (byte) ((this.data[byteIndex] & ~(this.mask << bitOffset)) | (newValue & this.mask) << bitOffset);
return currentValue;
}
public void set(int index, int value) {
Validate.inclusiveBetween(0L, (this.size - 1), index);
Validate.inclusiveBetween(0L, this.mask, value);
int byteIndex = cellIndex(index);
int bitOffset = (index - byteIndex * this.valuesPerByte) * this.bits;
this.data[byteIndex] = (byte) ((this.data[byteIndex] & ~(this.mask << bitOffset)) | (value & this.mask) << bitOffset);
}
public int get(int index) {
Validate.inclusiveBetween(0L, (this.size - 1), index);
int byteIndex = cellIndex(index);
int bitOffset = (index - byteIndex * this.valuesPerByte) * this.bits;
return (this.data[byteIndex] >> bitOffset) & this.mask;
}
public byte[] getRaw() {
return this.data;
}
public int getSize() {
return this.size;
}
public int getBits() {
return this.bits;
}
}

View File

@@ -20,9 +20,10 @@ package com.volmit.iris.util.nbt.mca.palette;
import org.apache.commons.lang3.Validate;
import java.util.BitSet;
import java.util.function.IntConsumer;
public class MCABitStorage {
public class MCABitStorageLongArray {
private static final int[] MAGIC = new int[]{
-1, -1, 0, Integer.MIN_VALUE, 0, 0, 1431655765, 1431655765, 0, Integer.MIN_VALUE,
0, 1, 858993459, 858993459, 0, 715827882, 715827882, 0, 613566756, 613566756,
@@ -61,11 +62,11 @@ public class MCABitStorage {
private final int divideShift;
public MCABitStorage(int bits, int length) {
public MCABitStorageLongArray(int bits, int length) {
this(bits, length, null);
}
public MCABitStorage(int bits, int length, long[] data) {
public MCABitStorageLongArray(int bits, int length, long[] data) {
Validate.inclusiveBetween(1L, 32L, bits);
this.size = length;
this.bits = bits;

View File

@@ -41,7 +41,8 @@ public class MCAPalettedContainer<T> implements MCAPaletteResize<T> {
private final T defaultValue;
protected MCABitStorage storage;
// Todo multiple storage systems cause long isnt the only one?
protected MCABitStorageLongArray storage;
private MCAPalette<T> palette;
@@ -74,11 +75,11 @@ public class MCAPalettedContainer<T> implements MCAPaletteResize<T> {
this.bits = MCAMth.ceillog2(this.registry.size());
}
this.palette.idFor(this.defaultValue);
this.storage = new MCABitStorage(this.bits, 4096);
this.storage = new MCABitStorageLongArray(this.bits, 4096);
}
public int onResize(int var0, T var1) {
MCABitStorage var2 = this.storage;
MCABitStorageLongArray var2 = this.storage;
MCAPalette<T> var3 = this.palette;
setBits(var0);
for (int var4 = 0; var4 < var2.getSize(); var4++) {
@@ -121,6 +122,12 @@ public class MCAPalettedContainer<T> implements MCAPaletteResize<T> {
T var1 = this.palette.valueFor(this.storage.get(var0));
return (var1 == null) ? this.defaultValue : var1;
}
/**
/**
* Reads and processes block data from encoded byte arrays.
* @param var0 BlockID Strings - List of block types identified by strings.
* @param var1 Encoded Locations - Long array containing compactly encoded block IDs, representing sequential block positions within a chunk.
*/
public void read(ListTag var0, long[] var1) {
int var2 = Math.max(4, MCAMth.ceillog2(var0.size()));
@@ -131,18 +138,69 @@ public class MCAPalettedContainer<T> implements MCAPaletteResize<T> {
if (this.palette == this.globalPalette) {
MCAPalette<T> var4 = new MCAHashMapPalette<>(this.registry, var2, this.dummyPaletteResize, this.reader, this.writer);
var4.read(var0);
MCABitStorage var5 = new MCABitStorage(var2, 4096, var1);
MCABitStorageLongArray var5 = new MCABitStorageLongArray(var2, 4096, var1);
for (int var6 = 0; var6 < 4096; var6++)
this.storage.set(var6, this.globalPalette.idFor(var4.valueFor(var5.get(var6))));
} else if (var3 == this.bits) {
System.arraycopy(var1, 0, this.storage.getRaw(), 0, var1.length);
} else {
MCABitStorage var4 = new MCABitStorage(var3, 4096, var1);
MCABitStorageLongArray var4 = new MCABitStorageLongArray(var3, 4096, var1);
for (int var5 = 0; var5 < 4096; var5++)
this.storage.set(var5, var4.get(var5));
}
}
/**
* Reads and processes block data from encoded byte arrays.
* @param var0 BlockID Strings - List of block types identified by strings.
* @param var1 Encoded Locations - Byte array containing compactly encoded block IDs, representing sequential block positions within a chunk.
* Currently, Minecraft doesn't use ByteArray storage.
*/
public void read(ListTag var0, byte[] var1) {
int requiredBits = Math.max(4, MCAMth.ceillog2(var0.size()));
if (requiredBits != this.bits) {
setBits(requiredBits);
}
this.palette.read(var0);
int bitsPerByte = 8 * var1.length / 4096;
if (this.palette == this.globalPalette) {
MCAPalette<T> var4 = new MCAHashMapPalette<>(this.registry, requiredBits, this.dummyPaletteResize, this.reader, this.writer);
var4.read(var0);
MCABitStorageByteArray var5 = new MCABitStorageByteArray(requiredBits, 4096, var1);
for (int var6 = 0; var6 < 4096; var6++) {
this.storage.set(var6, this.globalPalette.idFor(var4.valueFor(var5.get(var6))));
}
} else if (bitsPerByte == this.bits) {
System.arraycopy(var1, 0, this.storage.getRaw(), 0, var1.length);
} else {
MCABitStorageByteArray var4 = new MCABitStorageByteArray(bitsPerByte, 4096, var1);
for (int var5 = 0; var5 < 4096; var5++) {
this.storage.set(var5, var4.get(var5));
}
}
}
/**
* Reads and processes block data from encoded byte arrays.
* @param var0 BlockID Strings - List of block types identified by strings.
* This method is primarily used to read air sections.
*/
public void read(ListTag var0) {
int requiredBits = Math.max(4, MCAMth.ceillog2(var0.size()));
if (requiredBits != this.bits) {
setBits(requiredBits);
}
this.palette.read(var0);
int defaultValue = 0;
for (int i = 0; i < 4096; i++) {
this.storage.set(i, defaultValue);
}
}
public void write(CompoundTag var0, String var1, String var2) {
MCAHashMapPalette<T> var3 = new MCAHashMapPalette<>(this.registry, this.bits, this.dummyPaletteResize, this.reader, this.writer);
T var4 = this.defaultValue;
@@ -160,7 +218,7 @@ public class MCAPalettedContainer<T> implements MCAPaletteResize<T> {
var3.write(paletteList);
var0.put(var1, paletteList);
int var8 = Math.max(4, MCAMth.ceillog2(paletteList.size()));
MCABitStorage var9 = new MCABitStorage(var8, 4096);
MCABitStorageLongArray var9 = new MCABitStorageLongArray(var8, 4096);
for (int var10 = 0; var10 < var6.length; var10++) {
var9.set(var10, var6[var10]);
}

View File

@@ -18,7 +18,10 @@
package com.volmit.iris.util.nbt.mca.palette;
import com.volmit.iris.Iris;
import com.volmit.iris.util.nbt.tag.ByteArrayTag;
import com.volmit.iris.util.nbt.tag.CompoundTag;
import com.volmit.iris.util.nbt.tag.LongArrayTag;
import lombok.RequiredArgsConstructor;
import java.util.function.Function;
@@ -42,7 +45,22 @@ public class MCAWrappedPalettedContainer<T> implements MCAPaletteAccess {
}
public void readFromSection(CompoundTag tag) {
//container.read(tag.getListTag("palette"), tag.getLongArrayTag("block_states").getValue());
container.read(tag.getCompoundTag("block_states").getListTag("palette"), tag.getCompoundTag("block_states").getLongArrayTag("data").getValue());
// container.read(tag.getCompoundTag("block_states").getListTag("palette"), tag.getCompoundTag("block_states").getLongArrayTag("data").getValue());
CompoundTag blockStates = tag.getCompoundTag("block_states");
if (blockStates == null) {
throw new IllegalArgumentException("block_states tag is missing");
}
LongArrayTag longData = blockStates.getLongArrayTag("data");
if (longData != null && longData.getValue() != null) {
container.read(tag.getCompoundTag("block_states").getListTag("palette"), tag.getCompoundTag("block_states").getLongArrayTag("data").getValue());
} else {
ByteArrayTag byteData = blockStates.getByteArrayTag("data");
if (byteData == null) {
container.read(tag.getCompoundTag("block_states").getListTag("palette"));
} else {
throw new IllegalArgumentException("No palette data tag found or data value is null");
}
}
}
}

View File

@@ -6,6 +6,8 @@ authors: [ cyberpwn, NextdoorPsycho, Vatuu ]
website: volmit.com
description: More than a Dimension!
libraries:
- org.bytedeco:cuda-platform:12.3-8.9-1.5.10
- org.bytedeco:javacpp:1.5.10
- net.bytebuddy:byte-buddy:1.14.14
- net.bytebuddy:byte-buddy-agent:1.12.8
- com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2