9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2026-01-06 15:51:30 +00:00

Fix /iris object convert for .schem files with 128+ block types

This commit is contained in:
piexel
2025-12-18 11:25:38 +01:00
committed by Julian Krings
parent 025fa833c4
commit a4c5f46c37

View File

@@ -2,29 +2,21 @@ package com.volmit.iris.core.tools;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.object.*;
import com.volmit.iris.util.data.Varint;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.nbt.io.NBTUtil;
import com.volmit.iris.util.nbt.io.NamedTag;
import com.volmit.iris.util.nbt.tag.*;
import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.reflect.V;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import org.apache.commons.io.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.util.FileUtil;
import org.bukkit.util.Vector;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.io.*;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
@@ -39,13 +31,17 @@ public class IrisConverter {
sender.sendMessage("No schematic files to convert found in " + folder.getAbsolutePath());
return;
}
AtomicInteger counter = new AtomicInteger(0);
var stopwatch = PrecisionStopwatch.start();
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(() -> {
for (File schem : fileList) {
try {
for (File schem : fileList) {
try {
PrecisionStopwatch p = PrecisionStopwatch.start();
IrisObject object;
boolean largeObject = false;
NamedTag tag = null;
NamedTag tag;
try {
tag = NBTUtil.read(schem);
} catch (IOException e) {
@@ -53,17 +49,20 @@ public class IrisConverter {
throw new RuntimeException(e);
}
CompoundTag compound = (CompoundTag) tag.getTag();
int version = resolveVersion(compound);
if (!(version == 2 || version == 3))
throw new RuntimeException(C.RED + "Unsupported schematic version: " + version);
if (compound.containsKey("Palette") && compound.containsKey("Width") && compound.containsKey("Height") && compound.containsKey("Length")) {
compound = version == 3 ? (CompoundTag) compound.get("Schematic") : compound;
int objW = ((ShortTag) compound.get("Width")).getValue();
int objH = ((ShortTag) compound.get("Height")).getValue();
int objD = ((ShortTag) compound.get("Length")).getValue();
int i = -1;
int mv = objW * objH * objD;
AtomicInteger v = new AtomicInteger(0);
if (mv > 500_000) {
if (mv > 2_000_000) {
largeObject = true;
Iris.info(C.GRAY + "Converting.. "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
Iris.info(C.GRAY + "Converting.. " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
Iris.info(C.GRAY + "- It may take a while");
if (sender.isPlayer()) {
i = J.ar(() -> {
@@ -72,6 +71,7 @@ public class IrisConverter {
}
}
compound = version == 3 ? (CompoundTag) compound.get("Blocks") : compound;
CompoundTag paletteTag = (CompoundTag) compound.get("Palette");
Map<Integer, BlockData> blockmap = new HashMap<>(paletteTag.size(), 0.9f);
for (Map.Entry<String, Tag<?>> entry : paletteTag.getValue().entrySet()) {
@@ -82,14 +82,16 @@ public class IrisConverter {
blockmap.put(blockId, bd);
}
ByteArrayTag byteArray = (ByteArrayTag) compound.get("BlockData");
boolean isBytes = version == 3 ? compound.getByteArrayTag("Data").length() < 128 : ((IntTag) compound.get("PaletteMax")).getValue() < 128;
ByteArrayTag byteArray = version == 3 ? (ByteArrayTag) compound.get("Data") : (ByteArrayTag) compound.get("BlockData");
byte[] originalBlockArray = byteArray.getValue();
IrisObject object = new IrisObject(objW, objH, objD);
var din = new DataInputStream(new ByteArrayInputStream(originalBlockArray));
object = new IrisObject(objW, objH, objD);
for (int h = 0; h < objH; h++) {
for (int d = 0; d < objD; d++) {
for (int w = 0; w < objW; w++) {
BlockData bd = blockmap.get(Byte.toUnsignedInt(originalBlockArray[v.get()]));
int blockIndex = isBytes ? din.read() & 0xFF : Varint.readUnsignedVarInt(din);
BlockData bd = blockmap.get(blockIndex);
if (!bd.getMaterial().isAir()) {
object.setUnsigned(w, h, d, bd);
}
@@ -97,42 +99,59 @@ public class IrisConverter {
}
}
}
if (i != -1) J.car(i);
try {
object.shrinkwrap();
object.write(new File(folder, schem.getName().replace(".schem", ".iob")));
} catch (IOException e) {
Iris.info(C.RED + "Failed to save: " + schem.getName());
throw new RuntimeException(e);
}
if (sender.isPlayer()) {
if (largeObject) {
sender.sendMessage(C.IRIS + "Converted "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis()));
} else {
sender.sendMessage(C.IRIS + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
counter.incrementAndGet();
if (sender.isPlayer()) {
if (largeObject) {
sender.sendMessage(C.IRIS + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis()));
} else {
sender.sendMessage(C.IRIS + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
}
}
if (largeObject) {
Iris.info(C.GRAY + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis()));
} else {
Iris.info(C.GRAY + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
}
FileUtils.delete(schem);
} catch (IOException e) {
sender.sendMessage(C.RED + "Failed to save: " + schem.getName());
throw new IOException(e);
}
if (largeObject) {
Iris.info(C.GRAY + "Converted "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis()));
} else {
Iris.info(C.GRAY + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
}
FileUtils.delete(schem);
}
} catch (Exception e) {
Iris.info(C.RED + "Failed to convert: " + schem.getName());
if (sender.isPlayer()) {
} catch (Exception e) {
sender.sendMessage(C.RED + "Failed to convert: " + schem.getName());
e.printStackTrace();
}
e.printStackTrace();
Iris.reportError(e);
}
}
sender.sendMessage(C.GRAY + "converted: " + fileList.length);
stopwatch.end();
if (counter.get() != 0) {
sender.sendMessage(C.GRAY + "Converted: " + counter.get() + " in " + Form.duration(stopwatch.getMillis()));
}
if (counter.get() < fileList.length) {
sender.sendMessage(C.RED + "Some schematics failed to convert. Check the console for details.");
}
});
}
private static int resolveVersion(CompoundTag compound) throws Exception {
try {
IntTag root = compound.getIntTag("Version");
if (root != null) {
return root.getValue();
}
CompoundTag schematic = (CompoundTag) compound.get("Schematic");
return schematic.getIntTag("Version").getValue();
} catch (NullPointerException e) {
throw new Exception("Cannot resolve schematic version", e);
}
}
}