From e319efdc1e45b68f1a2c9f65d2f8436116492b67 Mon Sep 17 00:00:00 2001 From: piexel Date: Wed, 8 Oct 2025 15:18:37 +0200 Subject: [PATCH 01/13] Shrink not properly shrinking fix. --- .../volmit/iris/engine/object/IrisObject.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java index fb6a85d4e..da8d1e561 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -511,10 +511,28 @@ public void shrinkwrap() { max.setZ(Math.max(max.getZ(), i.getZ())); } + KMap temp = new KMap<>(); + w = max.getBlockX() - min.getBlockX() + 1; h = max.getBlockY() - min.getBlockY() + 1; d = max.getBlockZ() - min.getBlockZ() + 1; + + int dx = -Math.floorDiv(w, 2) - min.getBlockX(); + int dy = -Math.floorDiv(h, 2) - min.getBlockY(); + int dz = -Math.floorDiv(d, 2) - min.getBlockZ(); + + for (var entry : blocks.entrySet()) { + Vector3i oldPos = entry.getKey(); + Vector3i newPos = new Vector3i( + oldPos.getBlockX() + dx, + oldPos.getBlockY() + dy, + oldPos.getBlockZ() + dz + ); + temp.put(newPos, entry.getValue()); + } + center = new Vector3i(w / 2, h / 2, d / 2); + blocks = temp; } public void clean() { @@ -1011,6 +1029,8 @@ public int place(int x, int yv, int z, IObjectPlacer oplacer, IrisObjectPlacemen boolean place = !data.getMaterial().equals(Material.AIR) && !data.getMaterial().equals(Material.CAVE_AIR) && !wouldReplace; if (data instanceof IrisCustomData || place) { + + placer.set(xx, yy, zz, data); if (tile != null) { placer.setTile(xx, yy, zz, tile); From bab87dce928ec9de4c685f71e51ccef6f1990911 Mon Sep 17 00:00:00 2001 From: piexel Date: Wed, 8 Oct 2025 18:06:28 +0200 Subject: [PATCH 02/13] Adds a dev cmd to fix objects to use the correct boundary box. --- .../iris/core/commands/CommandDeveloper.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java index 5b0ab41cf..d1a24401f 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java @@ -52,11 +52,17 @@ import com.volmit.iris.util.nbt.mca.MCAUtil; import com.volmit.iris.util.parallel.MultiBurst; import com.volmit.iris.util.plugin.VolmitSender; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; import lombok.SneakyThrows; import net.jpountz.lz4.LZ4BlockInputStream; import net.jpountz.lz4.LZ4BlockOutputStream; import net.jpountz.lz4.LZ4FrameInputStream; import net.jpountz.lz4.LZ4FrameOutputStream; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOCase; +import org.apache.commons.io.filefilter.IOFileFilter; +import org.apache.commons.io.filefilter.SuffixFileFilter; +import org.apache.commons.io.filefilter.TrueFileFilter; import org.apache.commons.lang.RandomStringUtils; import org.bukkit.Bukkit; import org.bukkit.Chunk; @@ -70,7 +76,9 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; @@ -92,6 +100,38 @@ public void Sentry() { Iris.reportError(new Exception("This is a test")); } + @Decree(description = "Dev cmd to fix all the broken objects caused by faulty shrinkwarp") + public void unfuckAllObjects( + @Param(aliases = "dimension", description = "The dimension type to create the world with", defaultValue = "default") + IrisDimension type + ) { + IrisData dm = IrisData.get(Iris.instance.getDataFolder("packs", type.getLoadKey())); + IOFileFilter iobFilter = new SuffixFileFilter(".iob", IOCase.INSENSITIVE); + Collection iobFiles = FileUtils.listFiles( + new File("plugins/iris/packs/" + type.getLoadKey()), + iobFilter, + TrueFileFilter.INSTANCE + ); + AtomicInteger size = new AtomicInteger(iobFiles.size()); + var ps = PrecisionStopwatch.start(); + sender().sendMessage("Found " + size + " objects in " + type.getFolderName()); + iobFiles.parallelStream().forEach(file -> { + try { + String p = file.getPath().split(type.getLoadKey() + Pattern.quote(File.separator + "objects" + File.separator))[1].replace(".iob", ""); + var o = IrisData.loadAnyObject(p, dm); + o.shrinkwrap(); + o.write(o.getLoadFile()); + size.getAndDecrement(); + Iris.debug("Processed: " + o.getLoadKey() + ", Left: " + size.get()); + } catch (Exception e) { + Iris.info("Failed to process: " + file.getPath()); + } + }); + ps.end(); + Iris.info("Took: " + Form.duration(ps.getMillis())); + Iris.info(size + " Failed"); + } + @Decree(description = "Test") public void mantle(@Param(defaultValue = "false") boolean plate, @Param(defaultValue = "21474836474") String name) throws Throwable { var base = Iris.instance.getDataFile("dump", "pv." + name + ".ttp.lz4b.bin"); From 148379a178e5586469f5fce625a5b5254d793391 Mon Sep 17 00:00:00 2001 From: piexel Date: Sun, 12 Oct 2025 17:41:29 +0200 Subject: [PATCH 03/13] Fixed editor unable to open due to the previous editor not being able to be closed due to being null. --- core/src/main/java/com/volmit/iris/core/edit/JigsawEditor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/edit/JigsawEditor.java b/core/src/main/java/com/volmit/iris/core/edit/JigsawEditor.java index 2b20693be..5b3fb36a4 100644 --- a/core/src/main/java/com/volmit/iris/core/edit/JigsawEditor.java +++ b/core/src/main/java/com/volmit/iris/core/edit/JigsawEditor.java @@ -65,10 +65,10 @@ public JigsawEditor(Player player, IrisJigsawPiece piece, IrisObject object, Fil editors.get(player).close(); } - editors.put(player, this); if (object == null) { throw new RuntimeException("Object is null! " + piece.getObject()); } + editors.put(player, this); this.object = object; this.player = player; origin = player.getLocation().clone().add(0, 7, 0); From 406a5a8bc14abf1a8b6202fecbc71de862b143e9 Mon Sep 17 00:00:00 2001 From: piexel Date: Sun, 12 Oct 2025 17:41:52 +0200 Subject: [PATCH 04/13] Fix studio opening failure when not in spectator mode --- .../src/main/java/com/volmit/iris/core/project/IrisProject.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/project/IrisProject.java b/core/src/main/java/com/volmit/iris/core/project/IrisProject.java index 7e753f5c0..ec9578b24 100644 --- a/core/src/main/java/com/volmit/iris/core/project/IrisProject.java +++ b/core/src/main/java/com/volmit/iris/core/project/IrisProject.java @@ -225,7 +225,7 @@ public void open(VolmitSender sender, long seed, Consumer onDone) throws sender.sendMessage("Can't find dimension: " + getName()); return; } else if (sender.isPlayer()) { - sender.player().setGameMode(GameMode.SPECTATOR); + J.s(() -> sender.player().setGameMode(GameMode.SPECTATOR)); } try { From df4b9fa48f23127613266c2b7e687d481b108fb1 Mon Sep 17 00:00:00 2001 From: piexel Date: Sun, 12 Oct 2025 17:42:36 +0200 Subject: [PATCH 05/13] Fix /iris object convert for .schem files with 128+ block types and increase the threshold for when an object is considered large. --- .../volmit/iris/core/tools/IrisConverter.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java index 2dafd3156..4a3caf5e2 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java @@ -45,7 +45,7 @@ public static void convertSchematics(VolmitSender sender) { try { PrecisionStopwatch p = PrecisionStopwatch.start(); boolean largeObject = false; - NamedTag tag = null; + NamedTag tag; try { tag = NBTUtil.read(schem); } catch (IOException e) { @@ -61,7 +61,7 @@ public static void convertSchematics(VolmitSender sender) { 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 + "- It may take a while"); @@ -82,14 +82,30 @@ public static void convertSchematics(VolmitSender sender) { blockmap.put(blockId, bd); } + boolean isBytes = ((IntTag) compound.get("PaletteMax")).getValue() < 128; ByteArrayTag byteArray = (ByteArrayTag) compound.get("BlockData"); byte[] originalBlockArray = byteArray.getValue(); + int arrayIndex = 0; IrisObject 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; + if (isBytes) { + blockIndex = originalBlockArray[arrayIndex++] & 0xFF; + } else { + int value = 0; + int shift = 0; + byte b; + do { + b = originalBlockArray[arrayIndex++]; + value |= (b & 0x7F) << shift; + shift += 7; + } while ((b & 0x80) != 0); + blockIndex = value; + } + BlockData bd = blockmap.get(blockIndex); if (!bd.getMaterial().isAir()) { object.setUnsigned(w, h, d, bd); } From f7917cb038cb27d08cf50e76a4df7e1db32557c0 Mon Sep 17 00:00:00 2001 From: piexel Date: Sun, 12 Oct 2025 19:51:02 +0200 Subject: [PATCH 06/13] Add shrinkwrap legacy mode to restore old behavior for compatibility --- .../com/volmit/iris/core/IrisSettings.java | 1 + .../volmit/iris/engine/object/IrisObject.java | 49 +++++++++++++------ .../com/volmit/iris/util/matter/Matter.java | 2 +- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index 212b1551f..ba83c5862 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -244,6 +244,7 @@ public static class IrisSettingsGenerator { public boolean preventLeafDecay = true; public boolean useMulticore = false; public boolean offsetNoiseTypes = false; + public boolean useShrinkWrapFix = false; public boolean earlyCustomBlocks = false; } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java index da8d1e561..77aeec507 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -19,6 +19,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; @@ -498,7 +499,21 @@ public void write(File file, VolmitSender sender) throws IOException { out.close(); } + /** + * Shrinks the structure's bounding box to fit exactly around existing blocks + * and re-centers them around the new center point. + */ public void shrinkwrap() { + shrinkwrap(false); + } + + /** + * Shrinks the structure's bounding box to fit exactly around existing blocks + * and re-centers them around the new center point. + * + * @param legacy If true, preserves old behavior where blocks are not recentered + */ + public void shrinkwrap(boolean legacy) { BlockVector min = new BlockVector(); BlockVector max = new BlockVector(); @@ -511,28 +526,30 @@ public void shrinkwrap() { max.setZ(Math.max(max.getZ(), i.getZ())); } - KMap temp = new KMap<>(); - w = max.getBlockX() - min.getBlockX() + 1; h = max.getBlockY() - min.getBlockY() + 1; d = max.getBlockZ() - min.getBlockZ() + 1; - int dx = -Math.floorDiv(w, 2) - min.getBlockX(); - int dy = -Math.floorDiv(h, 2) - min.getBlockY(); - int dz = -Math.floorDiv(d, 2) - min.getBlockZ(); - - for (var entry : blocks.entrySet()) { - Vector3i oldPos = entry.getKey(); - Vector3i newPos = new Vector3i( - oldPos.getBlockX() + dx, - oldPos.getBlockY() + dy, - oldPos.getBlockZ() + dz - ); - temp.put(newPos, entry.getValue()); + if (!legacy || IrisSettings.get().getGenerator().useShrinkWrapFix) { + KMap temp = new KMap<>(); + + int dx = -Math.floorDiv(w, 2) - min.getBlockX(); + int dy = -Math.floorDiv(h, 2) - min.getBlockY(); + int dz = -Math.floorDiv(d, 2) - min.getBlockZ(); + + for (var entry : blocks.entrySet()) { + Vector3i oldPos = entry.getKey(); + Vector3i newPos = new Vector3i( + oldPos.getBlockX() + dx, + oldPos.getBlockY() + dy, + oldPos.getBlockZ() + dz + ); + temp.put(newPos, entry.getValue()); + } + blocks = temp; } center = new Vector3i(w / 2, h / 2, d / 2); - blocks = temp; } public void clean() { @@ -1172,7 +1189,7 @@ public void rotate(IrisObjectRotation r, int spinx, int spiny, int spinz) { blocks = d; states = dx; - shrinkwrap(); + shrinkwrap(true); } public void place(Location at) { diff --git a/core/src/main/java/com/volmit/iris/util/matter/Matter.java b/core/src/main/java/com/volmit/iris/util/matter/Matter.java index 0fe0dca0c..d6233d46c 100644 --- a/core/src/main/java/com/volmit/iris/util/matter/Matter.java +++ b/core/src/main/java/com/volmit/iris/util/matter/Matter.java @@ -81,7 +81,7 @@ static long convert(File folder) { static Matter from(IrisObject object) { object.clean(); - object.shrinkwrap(); + object.shrinkwrap(true); BlockVector min = new BlockVector(); Matter m = new IrisMatter(Math.max(object.getW(), 1) + 1, Math.max(object.getH(), 1) + 1, Math.max(object.getD(), 1) + 1); From 8e0f743264f1a526656effb7a097561cd06ff248 Mon Sep 17 00:00:00 2001 From: piexel Date: Mon, 13 Oct 2025 12:53:58 +0200 Subject: [PATCH 07/13] Improved IrisConverter to use Varint instead of a custom approach. --- .../volmit/iris/core/tools/IrisConverter.java | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java index 4a3caf5e2..aa16694af 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java @@ -2,6 +2,7 @@ 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; @@ -19,9 +20,7 @@ import org.bukkit.util.FileUtil; import org.bukkit.util.Vector; -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; +import java.io.*; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -86,25 +85,13 @@ public static void convertSchematics(VolmitSender sender) { ByteArrayTag byteArray = (ByteArrayTag) compound.get("BlockData"); byte[] originalBlockArray = byteArray.getValue(); int arrayIndex = 0; - + DataInputStream din = null; + if (!isBytes) din = new DataInputStream(new ByteArrayInputStream(originalBlockArray)); IrisObject 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++) { - int blockIndex; - if (isBytes) { - blockIndex = originalBlockArray[arrayIndex++] & 0xFF; - } else { - int value = 0; - int shift = 0; - byte b; - do { - b = originalBlockArray[arrayIndex++]; - value |= (b & 0x7F) << shift; - shift += 7; - } while ((b & 0x80) != 0); - blockIndex = value; - } + int blockIndex = isBytes ? originalBlockArray[arrayIndex++] & 0xFF : Varint.readUnsignedVarInt(din); BlockData bd = blockmap.get(blockIndex); if (!bd.getMaterial().isAir()) { object.setUnsigned(w, h, d, bd); From 429e7075fdd7cd48d241f61c8e3979ee347eb166 Mon Sep 17 00:00:00 2001 From: piexel Date: Mon, 13 Oct 2025 13:23:24 +0200 Subject: [PATCH 08/13] Improved IrisConverter to just use the stream. --- .../main/java/com/volmit/iris/core/tools/IrisConverter.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java index aa16694af..0ced57c7f 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java @@ -84,14 +84,12 @@ public static void convertSchematics(VolmitSender sender) { boolean isBytes = ((IntTag) compound.get("PaletteMax")).getValue() < 128; ByteArrayTag byteArray = (ByteArrayTag) compound.get("BlockData"); byte[] originalBlockArray = byteArray.getValue(); - int arrayIndex = 0; - DataInputStream din = null; - if (!isBytes) din = new DataInputStream(new ByteArrayInputStream(originalBlockArray)); + var din = new DataInputStream(new ByteArrayInputStream(originalBlockArray)); IrisObject 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++) { - int blockIndex = isBytes ? originalBlockArray[arrayIndex++] & 0xFF : Varint.readUnsignedVarInt(din); + int blockIndex = isBytes ? din.read() & 0xFF : Varint.readUnsignedVarInt(din); BlockData bd = blockmap.get(blockIndex); if (!bd.getMaterial().isAir()) { object.setUnsigned(w, h, d, bd); From d8dc094fe2a561e82be3d7a31c4c4bb86952d6e8 Mon Sep 17 00:00:00 2001 From: piexel Date: Mon, 13 Oct 2025 13:57:04 +0200 Subject: [PATCH 09/13] Improved IrisConverter with a timer cause why not --- .../main/java/com/volmit/iris/core/tools/IrisConverter.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java index 0ced57c7f..6f4eb14ae 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java @@ -38,6 +38,7 @@ public static void convertSchematics(VolmitSender sender) { sender.sendMessage("No schematic files to convert found in " + folder.getAbsolutePath()); return; } + var stopwatch = PrecisionStopwatch.start(); ExecutorService executorService = Executors.newFixedThreadPool(1); executorService.submit(() -> { for (File schem : fileList) { @@ -129,7 +130,8 @@ public static void convertSchematics(VolmitSender sender) { Iris.reportError(e); } } - sender.sendMessage(C.GRAY + "converted: " + fileList.length); + stopwatch.end(); + sender.sendMessage(C.GRAY + "converted: " + fileList.length + " in " + Form.duration(stopwatch.getMillis())); }); } From 049d4771e6b9dc78c09caef447795e52719c33aa Mon Sep 17 00:00:00 2001 From: piexel Date: Mon, 13 Oct 2025 19:38:48 +0200 Subject: [PATCH 10/13] Fix Grass won't place on moss blocks --- core/src/main/java/com/volmit/iris/util/data/B.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/java/com/volmit/iris/util/data/B.java b/core/src/main/java/com/volmit/iris/util/data/B.java index 982df8d2d..fa401fa44 100644 --- a/core/src/main/java/com/volmit/iris/util/data/B.java +++ b/core/src/main/java/com/volmit/iris/util/data/B.java @@ -360,6 +360,7 @@ public static boolean canPlaceOnto(Material mat, Material onto) { public static boolean isFoliagePlantable(BlockData d) { return d.getMaterial().equals(Material.GRASS_BLOCK) + || d.getMaterial().equals(Material.MOSS_BLOCK) || d.getMaterial().equals(Material.ROOTED_DIRT) || d.getMaterial().equals(Material.DIRT) || d.getMaterial().equals(Material.COARSE_DIRT) @@ -368,6 +369,7 @@ public static boolean isFoliagePlantable(BlockData d) { public static boolean isFoliagePlantable(Material d) { return d.equals(Material.GRASS_BLOCK) + || d.equals(Material.MOSS_BLOCK) || d.equals(Material.DIRT) || d.equals(TALL_GRASS) || d.equals(TALL_SEAGRASS) From af8060a58ff947ac5cd220d0d0150bc45cdaedef Mon Sep 17 00:00:00 2001 From: piexel Date: Thu, 16 Oct 2025 15:36:16 +0200 Subject: [PATCH 11/13] Adds proper handling for states when shrinkwraping and a new method for recentering positions outside shrinkwrap. --- .../volmit/iris/engine/object/IrisObject.java | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java index 77aeec507..82547f17e 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -82,6 +82,7 @@ public class IrisObject extends IrisRegistrant { protected transient IrisLock lock = new IrisLock("Preloadcache"); @Setter protected transient AtomicCache aabb = new AtomicCache<>(); + private Vector3i shrinkOffset; private KMap blocks; private KMap states; @Getter @@ -103,6 +104,7 @@ public IrisObject(int w, int h, int d) { this.w = w; this.h = h; this.d = d; + shrinkOffset = new Vector3i(0, 0, 0); center = new Vector3i(w / 2, h / 2, d / 2); } @@ -531,27 +533,44 @@ public void shrinkwrap(boolean legacy) { d = max.getBlockZ() - min.getBlockZ() + 1; if (!legacy || IrisSettings.get().getGenerator().useShrinkWrapFix) { - KMap temp = new KMap<>(); + KMap tb = new KMap<>(); + KMap tt = new KMap<>(); int dx = -Math.floorDiv(w, 2) - min.getBlockX(); int dy = -Math.floorDiv(h, 2) - min.getBlockY(); int dz = -Math.floorDiv(d, 2) - min.getBlockZ(); + shrinkOffset = new Vector3i(dx, dy, dz); for (var entry : blocks.entrySet()) { - Vector3i oldPos = entry.getKey(); - Vector3i newPos = new Vector3i( - oldPos.getBlockX() + dx, - oldPos.getBlockY() + dy, - oldPos.getBlockZ() + dz - ); - temp.put(newPos, entry.getValue()); + tb.put(applyRecentering(entry.getKey()), entry.getValue()); } - blocks = temp; + for (var entry : states.entrySet()) { + tt.put(applyRecentering(entry.getKey()), entry.getValue()); + } + + blocks = tb; + states = tt; } center = new Vector3i(w / 2, h / 2, d / 2); } + public Vector3i applyRecentering(Vector3i vec) { + return new Vector3i( + vec.getBlockX() + shrinkOffset.getBlockX(), + vec.getBlockY() + shrinkOffset.getBlockY(), + vec.getBlockZ() + shrinkOffset.getBlockZ() + ); + } + + public IrisPosition applyRecentering(IrisPosition pos) { + return new IrisPosition( + pos.getX() + shrinkOffset.getBlockX(), + pos.getY() + shrinkOffset.getBlockY(), + pos.getZ() + shrinkOffset.getBlockZ() + ); + } + public void clean() { KMap d = new KMap<>(); From 07597b02f5bdf43e85b37a13f9a06a461258093d Mon Sep 17 00:00:00 2001 From: piexel Date: Thu, 16 Oct 2025 15:38:05 +0200 Subject: [PATCH 12/13] Fixes a rare edge case for when shrinkwrapping broken objects that are out of bounds. --- .../main/java/com/volmit/iris/engine/object/IrisObject.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java index 82547f17e..f6274518a 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -516,8 +516,8 @@ public void shrinkwrap() { * @param legacy If true, preserves old behavior where blocks are not recentered */ public void shrinkwrap(boolean legacy) { - BlockVector min = new BlockVector(); - BlockVector max = new BlockVector(); + BlockVector min = new BlockVector(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); + BlockVector max = new BlockVector(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); for (BlockVector i : getBlocks().keySet()) { min.setX(Math.min(min.getX(), i.getX())); From d430d7e1f87ff9e836a0dccbbe065180e5c36d8f Mon Sep 17 00:00:00 2001 From: piexel Date: Thu, 16 Oct 2025 15:39:33 +0200 Subject: [PATCH 13/13] Improvements to UnfuckAllObjects to also unfuck the Jigsaw Connectors that were getting misaligned due to shrinkwrap. --- .../iris/core/commands/CommandDeveloper.java | 48 +++++++++++++------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java index d1a24401f..76fbd50c4 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java @@ -18,6 +18,7 @@ package com.volmit.iris.core.commands; +import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -31,6 +32,7 @@ import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.IrisDimension; +import com.volmit.iris.engine.object.IrisJigsawPiece; import com.volmit.iris.engine.object.annotations.Snippet; import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.context.IrisContext; @@ -45,6 +47,7 @@ import com.volmit.iris.util.format.Form; import com.volmit.iris.util.io.CountingDataInputStream; import com.volmit.iris.util.io.IO; +import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.mantle.TectonicPlate; import com.volmit.iris.util.math.M; import com.volmit.iris.util.matter.Matter; @@ -73,6 +76,7 @@ import java.net.NetworkInterface; import java.nio.file.Files; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; @@ -102,34 +106,48 @@ public void Sentry() { @Decree(description = "Dev cmd to fix all the broken objects caused by faulty shrinkwarp") public void unfuckAllObjects( - @Param(aliases = "dimension", description = "The dimension type to create the world with", defaultValue = "default") + @Param(aliases = "dimension", description = "The dimension type to create the world with", defaultValue = "null") IrisDimension type ) { - IrisData dm = IrisData.get(Iris.instance.getDataFolder("packs", type.getLoadKey())); - IOFileFilter iobFilter = new SuffixFileFilter(".iob", IOCase.INSENSITIVE); - Collection iobFiles = FileUtils.listFiles( - new File("plugins/iris/packs/" + type.getLoadKey()), - iobFilter, - TrueFileFilter.INSTANCE - ); - AtomicInteger size = new AtomicInteger(iobFiles.size()); + if (type == null) { + sender().sendMessage("Type cant be null?"); + return; + } var ps = PrecisionStopwatch.start(); + IrisData dm = IrisData.get(Iris.instance.getDataFolder("packs", type.getLoadKey())); + + ConcurrentHashMap cache = new ConcurrentHashMap<>(); + dm.getJigsawPieceLoader().streamAll().parallel().forEach(irisJigsawPiece -> { + try { + cache.put(dm.getObjectLoader().load(irisJigsawPiece.getObject()).getLoadFile().getPath(), irisJigsawPiece); + } catch (Exception e) { + e.printStackTrace(); + } + }); + + AtomicInteger size = new AtomicInteger(dm.getObjectLoader().getPossibleKeys().length); sender().sendMessage("Found " + size + " objects in " + type.getFolderName()); - iobFiles.parallelStream().forEach(file -> { + var gson = new Gson(); + dm.getObjectLoader().streamAll().parallel().forEach(o -> { try { - String p = file.getPath().split(type.getLoadKey() + Pattern.quote(File.separator + "objects" + File.separator))[1].replace(".iob", ""); - var o = IrisData.loadAnyObject(p, dm); o.shrinkwrap(); + if (cache.containsKey(o.getLoadFile().getPath())) { + var piece = cache.get(o.getLoadFile().getPath()); + piece.getConnectors().forEach(connector -> connector.setPosition(o.applyRecentering(connector.getPosition()))); + IO.writeAll(piece.getLoadFile(), new JSONObject(gson.toJson(piece)).toString(4)); + } o.write(o.getLoadFile()); size.getAndDecrement(); Iris.debug("Processed: " + o.getLoadKey() + ", Left: " + size.get()); } catch (Exception e) { - Iris.info("Failed to process: " + file.getPath()); + Iris.info("Failed to process: " + o.getLoadKey()); + e.printStackTrace(); } + }); ps.end(); - Iris.info("Took: " + Form.duration(ps.getMillis())); - Iris.info(size + " Failed"); + sender().sendMessage("Took: " + Form.duration(ps.getMillis())); + sender().sendMessage(size + " Failed"); } @Decree(description = "Test")