mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-06-18 14:50:57 +00:00
Fix /iris object convert for .schem files with 128+ block types
This commit is contained in:
@@ -2,29 +2,21 @@ package com.volmit.iris.core.tools;
|
|||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.engine.object.*;
|
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.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
import com.volmit.iris.util.nbt.io.NBTUtil;
|
import com.volmit.iris.util.nbt.io.NBTUtil;
|
||||||
import com.volmit.iris.util.nbt.io.NamedTag;
|
import com.volmit.iris.util.nbt.io.NamedTag;
|
||||||
import com.volmit.iris.util.nbt.tag.*;
|
import com.volmit.iris.util.nbt.tag.*;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
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.J;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.util.FileUtil;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.FilenameFilter;
|
import java.util.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@@ -39,13 +31,17 @@ public class IrisConverter {
|
|||||||
sender.sendMessage("No schematic files to convert found in " + folder.getAbsolutePath());
|
sender.sendMessage("No schematic files to convert found in " + folder.getAbsolutePath());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AtomicInteger counter = new AtomicInteger(0);
|
||||||
|
var stopwatch = PrecisionStopwatch.start();
|
||||||
ExecutorService executorService = Executors.newFixedThreadPool(1);
|
ExecutorService executorService = Executors.newFixedThreadPool(1);
|
||||||
executorService.submit(() -> {
|
executorService.submit(() -> {
|
||||||
for (File schem : fileList) {
|
for (File schem : fileList) {
|
||||||
try {
|
try {
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
|
IrisObject object;
|
||||||
boolean largeObject = false;
|
boolean largeObject = false;
|
||||||
NamedTag tag = null;
|
NamedTag tag;
|
||||||
try {
|
try {
|
||||||
tag = NBTUtil.read(schem);
|
tag = NBTUtil.read(schem);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -53,17 +49,20 @@ public class IrisConverter {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
CompoundTag compound = (CompoundTag) tag.getTag();
|
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 objW = ((ShortTag) compound.get("Width")).getValue();
|
||||||
int objH = ((ShortTag) compound.get("Height")).getValue();
|
int objH = ((ShortTag) compound.get("Height")).getValue();
|
||||||
int objD = ((ShortTag) compound.get("Length")).getValue();
|
int objD = ((ShortTag) compound.get("Length")).getValue();
|
||||||
int i = -1;
|
int i = -1;
|
||||||
int mv = objW * objH * objD;
|
int mv = objW * objH * objD;
|
||||||
AtomicInteger v = new AtomicInteger(0);
|
AtomicInteger v = new AtomicInteger(0);
|
||||||
if (mv > 500_000) {
|
if (mv > 2_000_000) {
|
||||||
largeObject = true;
|
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");
|
Iris.info(C.GRAY + "- It may take a while");
|
||||||
if (sender.isPlayer()) {
|
if (sender.isPlayer()) {
|
||||||
i = J.ar(() -> {
|
i = J.ar(() -> {
|
||||||
@@ -72,6 +71,7 @@ public class IrisConverter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compound = version == 3 ? (CompoundTag) compound.get("Blocks") : compound;
|
||||||
CompoundTag paletteTag = (CompoundTag) compound.get("Palette");
|
CompoundTag paletteTag = (CompoundTag) compound.get("Palette");
|
||||||
Map<Integer, BlockData> blockmap = new HashMap<>(paletteTag.size(), 0.9f);
|
Map<Integer, BlockData> blockmap = new HashMap<>(paletteTag.size(), 0.9f);
|
||||||
for (Map.Entry<String, Tag<?>> entry : paletteTag.getValue().entrySet()) {
|
for (Map.Entry<String, Tag<?>> entry : paletteTag.getValue().entrySet()) {
|
||||||
@@ -82,14 +82,16 @@ public class IrisConverter {
|
|||||||
blockmap.put(blockId, bd);
|
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();
|
byte[] originalBlockArray = byteArray.getValue();
|
||||||
|
var din = new DataInputStream(new ByteArrayInputStream(originalBlockArray));
|
||||||
IrisObject object = new IrisObject(objW, objH, objD);
|
object = new IrisObject(objW, objH, objD);
|
||||||
for (int h = 0; h < objH; h++) {
|
for (int h = 0; h < objH; h++) {
|
||||||
for (int d = 0; d < objD; d++) {
|
for (int d = 0; d < objD; d++) {
|
||||||
for (int w = 0; w < objW; w++) {
|
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()) {
|
if (!bd.getMaterial().isAir()) {
|
||||||
object.setUnsigned(w, h, d, bd);
|
object.setUnsigned(w, h, d, bd);
|
||||||
}
|
}
|
||||||
@@ -97,42 +99,59 @@ public class IrisConverter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != -1) J.car(i);
|
if (i != -1) J.car(i);
|
||||||
try {
|
try {
|
||||||
object.shrinkwrap();
|
object.shrinkwrap();
|
||||||
object.write(new File(folder, schem.getName().replace(".schem", ".iob")));
|
object.write(new File(folder, schem.getName().replace(".schem", ".iob")));
|
||||||
} catch (IOException e) {
|
counter.incrementAndGet();
|
||||||
Iris.info(C.RED + "Failed to save: " + schem.getName());
|
if (sender.isPlayer()) {
|
||||||
throw new RuntimeException(e);
|
if (largeObject) {
|
||||||
}
|
sender.sendMessage(C.IRIS + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis()));
|
||||||
if (sender.isPlayer()) {
|
} else {
|
||||||
if (largeObject) {
|
sender.sendMessage(C.IRIS + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
|
||||||
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 {
|
} catch (Exception e) {
|
||||||
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()) {
|
|
||||||
sender.sendMessage(C.RED + "Failed to convert: " + schem.getName());
|
sender.sendMessage(C.RED + "Failed to convert: " + schem.getName());
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
e.printStackTrace();
|
|
||||||
Iris.reportError(e);
|
|
||||||
}
|
}
|
||||||
}
|
stopwatch.end();
|
||||||
sender.sendMessage(C.GRAY + "converted: " + fileList.length);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user