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:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user